113521Sgabeblack@google.com/*****************************************************************************
213521Sgabeblack@google.com
313521Sgabeblack@google.com  Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
413521Sgabeblack@google.com  more contributor license agreements.  See the NOTICE file distributed
513521Sgabeblack@google.com  with this work for additional information regarding copyright ownership.
613521Sgabeblack@google.com  Accellera licenses this file to you under the Apache License, Version 2.0
713521Sgabeblack@google.com  (the "License"); you may not use this file except in compliance with the
813521Sgabeblack@google.com  License.  You may obtain a copy of the License at
913521Sgabeblack@google.com
1013521Sgabeblack@google.com    http://www.apache.org/licenses/LICENSE-2.0
1113521Sgabeblack@google.com
1213521Sgabeblack@google.com  Unless required by applicable law or agreed to in writing, software
1313521Sgabeblack@google.com  distributed under the License is distributed on an "AS IS" BASIS,
1413521Sgabeblack@google.com  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
1513521Sgabeblack@google.com  implied.  See the License for the specific language governing
1613521Sgabeblack@google.com  permissions and limitations under the License.
1713521Sgabeblack@google.com
1813521Sgabeblack@google.com *****************************************************************************/
1913521Sgabeblack@google.com
2013521Sgabeblack@google.com#ifndef __SYSTEMC_EXT_TLM_CORE_2_GENERIC_PAYLOAD_GP_HH__
2113521Sgabeblack@google.com#define __SYSTEMC_EXT_TLM_CORE_2_GENERIC_PAYLOAD_GP_HH__
2213521Sgabeblack@google.com
2313521Sgabeblack@google.com#include <typeinfo> // std::type_info
2413521Sgabeblack@google.com
2513586Sgabeblack@google.com#include "../../../utils/sc_report_handler.hh" // sc_assert
2613586Sgabeblack@google.com#include "array.hh"
2713521Sgabeblack@google.com
2813521Sgabeblack@google.comnamespace tlm
2913521Sgabeblack@google.com{
3013521Sgabeblack@google.com
3113521Sgabeblack@google.comclass tlm_generic_payload;
3213521Sgabeblack@google.com
3313521Sgabeblack@google.comclass tlm_mm_interface
3413521Sgabeblack@google.com{
3513521Sgabeblack@google.com  public:
3613521Sgabeblack@google.com    virtual void free(tlm_generic_payload *) = 0;
3713521Sgabeblack@google.com    virtual ~tlm_mm_interface() {}
3813521Sgabeblack@google.com};
3913521Sgabeblack@google.com
4013521Sgabeblack@google.com//---------------------------------------------------------------------------
4113521Sgabeblack@google.com// Classes and helpers for the extension mechanism
4213521Sgabeblack@google.com//---------------------------------------------------------------------------
4313521Sgabeblack@google.com// Helper function:
4413521Sgabeblack@google.comunsigned int max_num_extensions();
4513521Sgabeblack@google.com
4613521Sgabeblack@google.com// This class can be used for storing pointers to the extension classes, used
4713521Sgabeblack@google.com// in tlm_generic_payload:
4813521Sgabeblack@google.comclass tlm_extension_base
4913521Sgabeblack@google.com{
5013521Sgabeblack@google.com  public:
5113521Sgabeblack@google.com    virtual tlm_extension_base *clone() const = 0;
5213521Sgabeblack@google.com    virtual void free() { delete this; }
5313521Sgabeblack@google.com    virtual void copy_from(tlm_extension_base const &) = 0;
5413521Sgabeblack@google.com  protected:
5513521Sgabeblack@google.com    virtual ~tlm_extension_base() {}
5613521Sgabeblack@google.com    static unsigned int register_extension(const std::type_info &);
5713521Sgabeblack@google.com};
5813521Sgabeblack@google.com
5913521Sgabeblack@google.com// Base class for all extension classes, derive your extension class in
6013521Sgabeblack@google.com// the following way:
6113521Sgabeblack@google.com// class my_extension : public tlm_extension<my_extension> { ...
6213521Sgabeblack@google.com// This triggers proper extension registration during C++ static
6313521Sgabeblack@google.com// contruction time. my_extension::ID will hold the unique index in the
6413521Sgabeblack@google.com// tlm_generic_payload::m_extensions array.
6513521Sgabeblack@google.comtemplate <typename T>
6613521Sgabeblack@google.comclass tlm_extension : public tlm_extension_base
6713521Sgabeblack@google.com{
6813521Sgabeblack@google.com  public:
6913521Sgabeblack@google.com    virtual tlm_extension_base *clone() const = 0;
7013521Sgabeblack@google.com    virtual void copy_from(tlm_extension_base const &ext) = 0;
7113521Sgabeblack@google.com    virtual ~tlm_extension() {}
7213521Sgabeblack@google.com    const static unsigned int ID;
7313521Sgabeblack@google.com};
7413521Sgabeblack@google.com
7513521Sgabeblack@google.comtemplate <typename T>
7613521Sgabeblack@google.comconst unsigned int tlm_extension<T>::ID =
7713521Sgabeblack@google.com    tlm_extension_base::register_extension(typeid(T));
7813521Sgabeblack@google.com
7913521Sgabeblack@google.com//---------------------------------------------------------------------------
8013521Sgabeblack@google.com// enumeration types
8113521Sgabeblack@google.com//---------------------------------------------------------------------------
8213521Sgabeblack@google.comenum tlm_command
8313521Sgabeblack@google.com{
8413521Sgabeblack@google.com    TLM_READ_COMMAND,
8513521Sgabeblack@google.com    TLM_WRITE_COMMAND,
8613521Sgabeblack@google.com    TLM_IGNORE_COMMAND
8713521Sgabeblack@google.com};
8813521Sgabeblack@google.com
8913521Sgabeblack@google.comenum tlm_response_status
9013521Sgabeblack@google.com{
9113521Sgabeblack@google.com    TLM_OK_RESPONSE = 1,
9213521Sgabeblack@google.com    TLM_INCOMPLETE_RESPONSE = 0,
9313521Sgabeblack@google.com    TLM_GENERIC_ERROR_RESPONSE = -1,
9413521Sgabeblack@google.com    TLM_ADDRESS_ERROR_RESPONSE = -2,
9513521Sgabeblack@google.com    TLM_COMMAND_ERROR_RESPONSE = -3,
9613521Sgabeblack@google.com    TLM_BURST_ERROR_RESPONSE = -4,
9713521Sgabeblack@google.com    TLM_BYTE_ENABLE_ERROR_RESPONSE = -5
9813521Sgabeblack@google.com};
9913521Sgabeblack@google.com
10013521Sgabeblack@google.comenum tlm_gp_option
10113521Sgabeblack@google.com{
10213521Sgabeblack@google.com    TLM_MIN_PAYLOAD,
10313521Sgabeblack@google.com    TLM_FULL_PAYLOAD,
10413521Sgabeblack@google.com    TLM_FULL_PAYLOAD_ACCEPTED
10513521Sgabeblack@google.com};
10613521Sgabeblack@google.com
10713521Sgabeblack@google.com#define TLM_BYTE_DISABLED 0x0
10813521Sgabeblack@google.com#define TLM_BYTE_ENABLED 0xff
10913521Sgabeblack@google.com
11013521Sgabeblack@google.com//---------------------------------------------------------------------------
11113521Sgabeblack@google.com// The generic payload class:
11213521Sgabeblack@google.com//---------------------------------------------------------------------------
11313521Sgabeblack@google.com
11413521Sgabeblack@google.comextern template class tlm_array<tlm_extension_base *>;
11513521Sgabeblack@google.com
11613521Sgabeblack@google.comclass tlm_generic_payload
11713521Sgabeblack@google.com{
11813521Sgabeblack@google.com  public:
11913521Sgabeblack@google.com    tlm_generic_payload();
12013521Sgabeblack@google.com    explicit tlm_generic_payload(tlm_mm_interface *mm);
12113521Sgabeblack@google.com
12213521Sgabeblack@google.com    void
12313521Sgabeblack@google.com    acquire()
12413521Sgabeblack@google.com    {
12513521Sgabeblack@google.com        sc_assert(m_mm != 0);
12613521Sgabeblack@google.com        m_ref_count++;
12713521Sgabeblack@google.com    }
12813521Sgabeblack@google.com
12913521Sgabeblack@google.com    void
13013521Sgabeblack@google.com    release()
13113521Sgabeblack@google.com    {
13213521Sgabeblack@google.com        sc_assert(m_mm != 0 && m_ref_count > 0);
13313521Sgabeblack@google.com        if (--m_ref_count == 0)
13413521Sgabeblack@google.com            m_mm->free(this);
13513521Sgabeblack@google.com    }
13613521Sgabeblack@google.com
13713521Sgabeblack@google.com    int get_ref_count() const { return m_ref_count; }
13813521Sgabeblack@google.com
13913521Sgabeblack@google.com    void set_mm(tlm_mm_interface *mm) { m_mm = mm; }
14013521Sgabeblack@google.com    bool has_mm() const { return m_mm != 0; }
14113521Sgabeblack@google.com
14213521Sgabeblack@google.com    void reset();
14313521Sgabeblack@google.com
14413521Sgabeblack@google.com  private:
14513521Sgabeblack@google.com    // Disabled copy ctor and assignment operator.
14613521Sgabeblack@google.com    tlm_generic_payload(const tlm_generic_payload &x);
14713521Sgabeblack@google.com    tlm_generic_payload &operator = (const tlm_generic_payload &x);
14813521Sgabeblack@google.com
14913521Sgabeblack@google.com  public:
15013521Sgabeblack@google.com    // Non-virtual deep-copying of the object.
15113521Sgabeblack@google.com    void deep_copy_from(const tlm_generic_payload &other);
15213521Sgabeblack@google.com
15313521Sgabeblack@google.com    // To update the state of the original generic payload from a deep copy.
15413521Sgabeblack@google.com    // Assumes that "other" was created from the original by calling
15513521Sgabeblack@google.com    // deep_copy_from Argument use_byte_enable_on_read determines whether to
15613521Sgabeblack@google.com    // use or ignores byte enables when copying back the data array on a read
15713521Sgabeblack@google.com    // command.
15813521Sgabeblack@google.com
15913521Sgabeblack@google.com    void update_original_from(const tlm_generic_payload &other,
16013521Sgabeblack@google.com                              bool use_byte_enable_on_read=true);
16113521Sgabeblack@google.com
16213521Sgabeblack@google.com    void update_extensions_from(const tlm_generic_payload &other);
16313521Sgabeblack@google.com
16413521Sgabeblack@google.com    // Free all extensions. Useful when reusing a cloned transaction that
16513521Sgabeblack@google.com    // doesn't have memory manager. Normal and sticky extensions are freed and
16613521Sgabeblack@google.com    // extension array cleared.
16713521Sgabeblack@google.com    void free_all_extensions();
16813521Sgabeblack@google.com
16913521Sgabeblack@google.com    virtual ~tlm_generic_payload();
17013521Sgabeblack@google.com
17113521Sgabeblack@google.com    //----------------
17213521Sgabeblack@google.com    // API (including setters & getters).
17313521Sgabeblack@google.com    //---------------
17413521Sgabeblack@google.com
17513521Sgabeblack@google.com    // Command related method.
17613521Sgabeblack@google.com    bool is_read() const { return (m_command == TLM_READ_COMMAND); }
17713521Sgabeblack@google.com    void set_read() { m_command = TLM_READ_COMMAND; }
17813521Sgabeblack@google.com    bool is_write() const { return (m_command == TLM_WRITE_COMMAND); }
17913521Sgabeblack@google.com    void set_write() { m_command = TLM_WRITE_COMMAND; }
18013521Sgabeblack@google.com    tlm_command get_command() const { return m_command; }
18113521Sgabeblack@google.com    void set_command(const tlm_command command) { m_command = command; }
18213521Sgabeblack@google.com
18313521Sgabeblack@google.com    // Address related methods.
18413521Sgabeblack@google.com    sc_dt::uint64 get_address() const { return m_address; }
18513521Sgabeblack@google.com    void set_address(const sc_dt::uint64 address) { m_address = address; }
18613521Sgabeblack@google.com
18713521Sgabeblack@google.com    // Data related methods.
18813521Sgabeblack@google.com    unsigned char *get_data_ptr() const { return m_data; }
18913521Sgabeblack@google.com    void set_data_ptr(unsigned char *data) { m_data = data; }
19013521Sgabeblack@google.com
19113521Sgabeblack@google.com    // Transaction length (in bytes) related methods.
19213521Sgabeblack@google.com    unsigned int get_data_length() const { return m_length; }
19313521Sgabeblack@google.com    void set_data_length(const unsigned int length) { m_length = length; }
19413521Sgabeblack@google.com
19513521Sgabeblack@google.com    // Response status related methods.
19613521Sgabeblack@google.com    bool is_response_ok() const { return (m_response_status > 0); }
19713521Sgabeblack@google.com    bool is_response_error() const { return (m_response_status <= 0); }
19813521Sgabeblack@google.com    tlm_response_status
19913521Sgabeblack@google.com    get_response_status() const
20013521Sgabeblack@google.com    {
20113521Sgabeblack@google.com        return m_response_status;
20213521Sgabeblack@google.com    }
20313521Sgabeblack@google.com    void
20413521Sgabeblack@google.com    set_response_status(const tlm_response_status response_status)
20513521Sgabeblack@google.com    {
20613521Sgabeblack@google.com        m_response_status = response_status;
20713521Sgabeblack@google.com    }
20813521Sgabeblack@google.com    std::string get_response_string() const;
20913521Sgabeblack@google.com
21013521Sgabeblack@google.com    // Streaming related methods.
21113521Sgabeblack@google.com    unsigned int get_streaming_width() const { return m_streaming_width; }
21213521Sgabeblack@google.com    void
21313521Sgabeblack@google.com    set_streaming_width(const unsigned int streaming_width)
21413521Sgabeblack@google.com    {
21513521Sgabeblack@google.com        m_streaming_width = streaming_width;
21613521Sgabeblack@google.com    }
21713521Sgabeblack@google.com
21813521Sgabeblack@google.com    // Byte enable related methods.
21913521Sgabeblack@google.com    unsigned char *get_byte_enable_ptr() const { return m_byte_enable; }
22013521Sgabeblack@google.com    void
22113521Sgabeblack@google.com    set_byte_enable_ptr(unsigned char *byte_enable)
22213521Sgabeblack@google.com    {
22313521Sgabeblack@google.com        m_byte_enable = byte_enable;
22413521Sgabeblack@google.com    }
22513521Sgabeblack@google.com    unsigned int
22613521Sgabeblack@google.com    get_byte_enable_length() const
22713521Sgabeblack@google.com    {
22813521Sgabeblack@google.com        return m_byte_enable_length;
22913521Sgabeblack@google.com    }
23013521Sgabeblack@google.com    void
23113521Sgabeblack@google.com    set_byte_enable_length(const unsigned int byte_enable_length)
23213521Sgabeblack@google.com    {
23313521Sgabeblack@google.com        m_byte_enable_length = byte_enable_length;
23413521Sgabeblack@google.com    }
23513521Sgabeblack@google.com
23613521Sgabeblack@google.com    // This is the "DMI-hint" a slave can set this to true if it
23713521Sgabeblack@google.com    // wants to indicate that a DMI request would be supported:
23813521Sgabeblack@google.com    void
23913521Sgabeblack@google.com    set_dmi_allowed(bool dmi_allowed)
24013521Sgabeblack@google.com    {
24113521Sgabeblack@google.com        m_dmi = dmi_allowed;
24213521Sgabeblack@google.com    }
24313521Sgabeblack@google.com    bool
24413521Sgabeblack@google.com    is_dmi_allowed() const
24513521Sgabeblack@google.com    {
24613521Sgabeblack@google.com        return m_dmi;
24713521Sgabeblack@google.com    }
24813521Sgabeblack@google.com
24913521Sgabeblack@google.com    // Use full set of attributes in DMI/debug?
25013521Sgabeblack@google.com    tlm_gp_option get_gp_option() const { return m_gp_option; }
25113521Sgabeblack@google.com    void set_gp_option(const tlm_gp_option gp_opt) { m_gp_option = gp_opt; }
25213521Sgabeblack@google.com
25313521Sgabeblack@google.com  private:
25413521Sgabeblack@google.com    /* --------------------------------------------------------------------- */
25513521Sgabeblack@google.com    /* Generic Payload attributes:                                           */
25613521Sgabeblack@google.com    /* --------------------------------------------------------------------- */
25713521Sgabeblack@google.com    /* - m_command         : Type of transaction. Three values supported:    */
25813521Sgabeblack@google.com    /*                       - TLM_WRITE_COMMAND                             */
25913521Sgabeblack@google.com    /*                       - TLM_READ_COMMAND                              */
26013521Sgabeblack@google.com    /*                       - TLM_IGNORE_COMMAND                            */
26113521Sgabeblack@google.com    /* - m_address         : Transaction base address (byte-addressing).     */
26213521Sgabeblack@google.com    /* - m_data            : When m_command = TLM_WRITE_COMMAND contains a   */
26313521Sgabeblack@google.com    /*                       pointer to the data to be written in the target.*/
26413521Sgabeblack@google.com    /*                       When m_command = TLM_READ_COMMAND contains a    */
26513521Sgabeblack@google.com    /*                       pointer where to copy the data read from the    */
26613521Sgabeblack@google.com    /*                       target.                                         */
26713521Sgabeblack@google.com    /* - m_length          : Total number of bytes of the transaction.       */
26813521Sgabeblack@google.com    /* - m_response_status : This attribute indicates whether an error has   */
26913521Sgabeblack@google.com    /*                       occurred during the transaction.                */
27013521Sgabeblack@google.com    /*                       Values supported are:                           */
27113521Sgabeblack@google.com    /*                       - TLM_OK_RESP                                   */
27213521Sgabeblack@google.com    /*                       - TLM_INCOMPLETE_RESP                           */
27313521Sgabeblack@google.com    /*                       - TLM_GENERIC_ERROR_RESP                        */
27413521Sgabeblack@google.com    /*                       - TLM_ADDRESS_ERROR_RESP                        */
27513521Sgabeblack@google.com    /*                       - TLM_COMMAND_ERROR_RESP                        */
27613521Sgabeblack@google.com    /*                       - TLM_BURST_ERROR_RESP                          */
27713521Sgabeblack@google.com    /*                       - TLM_BYTE_ENABLE_ERROR_RESP                    */
27813521Sgabeblack@google.com    /*                                                                       */
27913521Sgabeblack@google.com    /* - m_byte_enable     : It can be used to create burst transfers where  */
28013521Sgabeblack@google.com    /*                    the address increment between each beat is greater */
28113521Sgabeblack@google.com    /*                    than the word length of each beat, or to place     */
28213521Sgabeblack@google.com    /*                    words in selected byte lanes of a bus.             */
28313521Sgabeblack@google.com    /* - m_byte_enable_length : For a read or a write command, the target    */
28413521Sgabeblack@google.com    /*                    interpret the byte enable length attribute as the  */
28513521Sgabeblack@google.com    /*                    number of elements in the bytes enable array.      */
28613521Sgabeblack@google.com    /* - m_streaming_width  :                                                */
28713521Sgabeblack@google.com    /* --------------------------------------------------------------------- */
28813521Sgabeblack@google.com
28913521Sgabeblack@google.com    sc_dt::uint64 m_address;
29013521Sgabeblack@google.com    tlm_command m_command;
29113521Sgabeblack@google.com    unsigned char *m_data;
29213521Sgabeblack@google.com    unsigned int m_length;
29313521Sgabeblack@google.com    tlm_response_status m_response_status;
29413521Sgabeblack@google.com    bool m_dmi;
29513521Sgabeblack@google.com    unsigned char *m_byte_enable;
29613521Sgabeblack@google.com    unsigned int m_byte_enable_length;
29713521Sgabeblack@google.com    unsigned int m_streaming_width;
29813521Sgabeblack@google.com    tlm_gp_option m_gp_option;
29913521Sgabeblack@google.com
30013521Sgabeblack@google.com  public:
30113521Sgabeblack@google.com    /* --------------------------------------------------------------------- */
30213521Sgabeblack@google.com    /* Dynamic extension mechanism:                                          */
30313521Sgabeblack@google.com    /* --------------------------------------------------------------------- */
30413521Sgabeblack@google.com    /* The extension mechanism is intended to enable initiator modules to    */
30513521Sgabeblack@google.com    /* optionally and transparently add data fields to the                   */
30613521Sgabeblack@google.com    /* tlm_generic_payload. Target modules are free to check for extensions  */
30713521Sgabeblack@google.com    /* and may or may not react to the data in the extension fields. The     */
30813521Sgabeblack@google.com    /* definition of the extensions' semantics is solely in the              */
30913521Sgabeblack@google.com    /* responsibility of the user.                                           */
31013521Sgabeblack@google.com    /*                                                                       */
31113521Sgabeblack@google.com    /* The following rules apply:                                            */
31213521Sgabeblack@google.com    /*                                                                       */
31313521Sgabeblack@google.com    /* - Every extension class must be derived from tlm_extension, e.g.:     */
31413521Sgabeblack@google.com    /*     class my_extension : public tlm_extension<my_extension> { ... }   */
31513521Sgabeblack@google.com    /*                                                                       */
31613521Sgabeblack@google.com    /* - A tlm_generic_payload object should be constructed after C++        */
31713521Sgabeblack@google.com    /*   static initialization time. This way it is guaranteed that the      */
31813521Sgabeblack@google.com    /*   extension array is of sufficient size to hold all possible          */
31913521Sgabeblack@google.com    /*   extensions. Alternatively, the initiator module can enforce a valid */
32013521Sgabeblack@google.com    /*   extension array size by calling the resize_extensions() method      */
32113521Sgabeblack@google.com    /*   once before the first transaction with the payload object is        */
32213521Sgabeblack@google.com    /*   initiated.                                                          */
32313521Sgabeblack@google.com    /*                                                                       */
32413521Sgabeblack@google.com    /* - Initiators should use the the set_extension(e) or clear_extension(e)*/
32513521Sgabeblack@google.com    /*   methods for manipulating the extension array. The type of the       */
32613521Sgabeblack@google.com    /*   argument must be a pointer to the specific registered extension     */
32713521Sgabeblack@google.com    /*   type (my_extension in the above example) and is used to             */
32813521Sgabeblack@google.com    /*   automatically locate the appropriate index in the array.            */
32913521Sgabeblack@google.com    /*                                                                       */
33013521Sgabeblack@google.com    /* - Targets can check for a specific extension by calling               */
33113521Sgabeblack@google.com    /*   get_extension(e). e will point to zero if the extension is not      */
33213521Sgabeblack@google.com    /*   present.                                                            */
33313521Sgabeblack@google.com    /*                                                                       */
33413521Sgabeblack@google.com    /* --------------------------------------------------------------------- */
33513521Sgabeblack@google.com
33613521Sgabeblack@google.com    // Stick the pointer to an extension into the vector, return the
33713521Sgabeblack@google.com    // previous value:
33813521Sgabeblack@google.com    template <typename T>
33913521Sgabeblack@google.com    T *
34013521Sgabeblack@google.com    set_extension(T *ext)
34113521Sgabeblack@google.com    {
34213521Sgabeblack@google.com        return static_cast<T *>(set_extension(T::ID, ext));
34313521Sgabeblack@google.com    }
34413521Sgabeblack@google.com
34513521Sgabeblack@google.com    // Non-templatized version with manual index:
34613521Sgabeblack@google.com    tlm_extension_base *set_extension(
34713521Sgabeblack@google.com            unsigned int index, tlm_extension_base *ext);
34813521Sgabeblack@google.com
34913521Sgabeblack@google.com    // Stick the pointer to an extension into the vector, return the
35013521Sgabeblack@google.com    // previous value and schedule its release.
35113521Sgabeblack@google.com    template <typename T>
35213521Sgabeblack@google.com    T *
35313521Sgabeblack@google.com    set_auto_extension(T *ext)
35413521Sgabeblack@google.com    {
35513521Sgabeblack@google.com        return static_cast<T *>(set_auto_extension(T::ID, ext));
35613521Sgabeblack@google.com    }
35713521Sgabeblack@google.com
35813521Sgabeblack@google.com    // Non-templatized version with manual index:
35913521Sgabeblack@google.com    tlm_extension_base *set_auto_extension(
36013521Sgabeblack@google.com            unsigned int index, tlm_extension_base *ext);
36113521Sgabeblack@google.com
36213521Sgabeblack@google.com    // Check for an extension, ext will point to 0 if not present.
36313521Sgabeblack@google.com    template <typename T>
36413521Sgabeblack@google.com    void get_extension(T *& ext) const { ext = get_extension<T>(); }
36513521Sgabeblack@google.com    template <typename T>
36613521Sgabeblack@google.com    T *
36713521Sgabeblack@google.com    get_extension() const
36813521Sgabeblack@google.com    {
36913521Sgabeblack@google.com        return static_cast<T*>(get_extension(T::ID));
37013521Sgabeblack@google.com    }
37113521Sgabeblack@google.com    // Non-templatized version with manual index:
37213521Sgabeblack@google.com    tlm_extension_base *get_extension(unsigned int index) const;
37313521Sgabeblack@google.com
37413521Sgabeblack@google.com    // This call just removes the extension from the txn but does not
37513521Sgabeblack@google.com    // call free() or tells the MM to do so it return false if there was
37613521Sgabeblack@google.com    // active MM so you are now in an unsafe situation recommended use:
37713521Sgabeblack@google.com    // when 100% sure there is no MM.
37813521Sgabeblack@google.com    template <typename T>
37913521Sgabeblack@google.com    void clear_extension(const T *ext) { clear_extension<T>(); }
38013521Sgabeblack@google.com
38113521Sgabeblack@google.com    // This call just removes the extension from the txn but does not
38213521Sgabeblack@google.com    // call free() or tells the MM to do so it return false if there was
38313521Sgabeblack@google.com    // active MM so you are now in an unsafe situation recommended use: when
38413521Sgabeblack@google.com    // 100% sure there is no MM.
38513521Sgabeblack@google.com    template <typename T>
38613521Sgabeblack@google.com    void clear_extension() { clear_extension(T::ID); }
38713521Sgabeblack@google.com
38813521Sgabeblack@google.com    // This call removes the extension from the txn and does call free() or
38913521Sgabeblack@google.com    // tells the MM to do so when the txn is finally done recommended use:
39013521Sgabeblack@google.com    // when not sure there is no MM.
39113521Sgabeblack@google.com    template <typename T>
39213521Sgabeblack@google.com    void release_extension(T *ext)
39313521Sgabeblack@google.com    {
39413521Sgabeblack@google.com        release_extension<T>();
39513521Sgabeblack@google.com    }
39613521Sgabeblack@google.com
39713521Sgabeblack@google.com    // This call removes the extension from the txn and does call free() or
39813521Sgabeblack@google.com    // tells the MM to do so when the txn is finally done recommended use:
39913521Sgabeblack@google.com    // when not sure there is no MM
40013521Sgabeblack@google.com    template <typename T>
40113521Sgabeblack@google.com    void release_extension()
40213521Sgabeblack@google.com    {
40313521Sgabeblack@google.com        release_extension(T::ID);
40413521Sgabeblack@google.com    }
40513521Sgabeblack@google.com
40613521Sgabeblack@google.com  private:
40713521Sgabeblack@google.com    // Non-templatized version with manual index
40813521Sgabeblack@google.com    void clear_extension(unsigned int index);
40913521Sgabeblack@google.com    // Non-templatized version with manual index
41013521Sgabeblack@google.com    void release_extension(unsigned int index);
41113521Sgabeblack@google.com
41213521Sgabeblack@google.com  public:
41313521Sgabeblack@google.com    // Make sure the extension array is large enough. Can be called once by
41413521Sgabeblack@google.com    // an initiator module (before issuing the first transaction) to make
41513521Sgabeblack@google.com    // sure that the extension array is of correct size. This is only needed
41613521Sgabeblack@google.com    // if the initiator cannot guarantee that the generic payload object is
41713521Sgabeblack@google.com    // allocated after C++ static construction time.
41813521Sgabeblack@google.com    void resize_extensions();
41913521Sgabeblack@google.com
42013521Sgabeblack@google.com  private:
42113521Sgabeblack@google.com    tlm_array<tlm_extension_base *> m_extensions;
42213521Sgabeblack@google.com    tlm_mm_interface *m_mm;
42313521Sgabeblack@google.com    unsigned int m_ref_count;
42413521Sgabeblack@google.com};
42513521Sgabeblack@google.com
42613521Sgabeblack@google.com} // namespace tlm
42713521Sgabeblack@google.com
42813521Sgabeblack@google.com#endif /* __SYSTEMC_EXT_TLM_CORE_2_GENERIC_PAYLOAD_GP_HH__ */
429