--- /dev/null
+# Copyright 2018 Google, Inc.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# Authors: Gabe Black
+
+Import('*')
+
+if env['USE_SYSTEMC']:
+ Source('tlm_gp.cc')
+ Source('tlm_phase.cc')
--- /dev/null
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+#include <cstring> // std::memcpy et.al.
+#include <map>
+#include <systemc>
+#include <tlm>
+
+using sc_core::sc_type_index;
+
+namespace tlm
+{
+
+template class tlm_array<tlm_extension_base *>;
+
+//---------------------------------------------------------------------------
+// Classes for the extension mechanism
+//---------------------------------------------------------------------------
+
+namespace
+{
+
+class tlm_extension_registry
+{
+ typedef unsigned int key_type;
+ typedef std::map<sc_core::sc_type_index, key_type> type_map;
+ public:
+ static tlm_extension_registry &
+ instance()
+ {
+ if (!instance_) {
+ // Don't cleanup registry.
+ instance_ = new tlm_extension_registry();
+ }
+ return *instance_;
+ }
+
+ unsigned int
+ register_extension(sc_type_index type)
+ {
+ type_map::const_iterator it = ids_.find(type);
+
+ if (it == ids_.end()) {
+ // New extension - generate/store ID.
+ type_map::value_type v(type, static_cast<key_type>(ids_.size()));
+ ids_.insert(v);
+ return v.second;
+ }
+ return it->second;
+ }
+
+ static unsigned int
+ max_num_extensions()
+ {
+ return (instance_) ? instance().ids_.size() : 0;
+ }
+
+ private:
+ static tlm_extension_registry *instance_;
+ type_map ids_;
+ tlm_extension_registry() {}
+
+};
+
+tlm_extension_registry *tlm_extension_registry::instance_ = NULL;
+
+} // anonymous namespace
+
+unsigned int
+max_num_extensions()
+{
+ return tlm_extension_registry::max_num_extensions();
+}
+
+unsigned int
+tlm_extension_base::register_extension(const std::type_info &type)
+{
+ return tlm_extension_registry::instance().register_extension(type);
+}
+
+//---------------------------------------------------------------------------
+// The generic payload class:
+//---------------------------------------------------------------------------
+
+tlm_generic_payload::tlm_generic_payload() : m_address(0),
+ m_command(TLM_IGNORE_COMMAND), m_data(0), m_length(0),
+ m_response_status(TLM_INCOMPLETE_RESPONSE), m_dmi(false), m_byte_enable(0),
+ m_byte_enable_length(0), m_streaming_width(0),
+ m_gp_option(TLM_MIN_PAYLOAD), m_extensions(max_num_extensions()), m_mm(0),
+ m_ref_count(0)
+{}
+
+tlm_generic_payload::tlm_generic_payload(tlm_mm_interface *mm): m_address(0),
+ m_command(TLM_IGNORE_COMMAND), m_data(0), m_length(0),
+ m_response_status(TLM_INCOMPLETE_RESPONSE), m_dmi(false), m_byte_enable(0),
+ m_byte_enable_length(0), m_streaming_width(0),
+ m_gp_option(TLM_MIN_PAYLOAD), m_extensions(max_num_extensions()), m_mm(mm),
+ m_ref_count(0)
+{}
+
+void
+tlm_generic_payload::reset()
+{
+ // Should the other members be reset too?
+ m_gp_option = TLM_MIN_PAYLOAD;
+ m_extensions.free_entire_cache();
+};
+
+// Non-virtual deep-copying of the object.
+void
+tlm_generic_payload::deep_copy_from(const tlm_generic_payload &other)
+{
+ m_command = other.get_command();
+ m_address = other.get_address();
+ m_length = other.get_data_length();
+ m_response_status = other.get_response_status();
+ m_byte_enable_length = other.get_byte_enable_length();
+ m_streaming_width = other.get_streaming_width();
+ m_gp_option = other.get_gp_option();
+ m_dmi = other.is_dmi_allowed();
+
+ // Deep copy data.
+ // There must be enough space in the target transaction!
+ if (m_data && other.m_data) {
+ std::memcpy(m_data, other.m_data, m_length);
+ }
+ // Deep copy byte enables.
+ // There must be enough space in the target transaction!
+ if (m_byte_enable && other.m_byte_enable) {
+ std::memcpy(m_byte_enable, other.m_byte_enable, m_byte_enable_length);
+ }
+ // Deep copy extensions (sticky and non-sticky).
+ if (m_extensions.size() < other.m_extensions.size()) {
+ m_extensions.expand(other.m_extensions.size());
+ }
+ for (unsigned int i = 0; i < other.m_extensions.size(); i++) {
+ if (other.m_extensions[i]) {
+ // Original has extension i.
+ if (!m_extensions[i]) {
+ // We don't: clone.
+ tlm_extension_base *ext = other.m_extensions[i]->clone();
+ if (ext) { // Extension may not be clonable.
+ if (has_mm()) {
+ // mm can take care of removing cloned extensions.
+ set_auto_extension(i, ext);
+ } else {
+ // no mm, user will call free_all_extensions().
+ set_extension(i, ext);
+ }
+ }
+ } else {
+ // We already have such extension. Copy original over it.
+ m_extensions[i]->copy_from(*other.m_extensions[i]);
+ }
+ }
+ }
+}
+
+// To update the state of the original generic payload from a deep copy.
+// Assumes that "other" was created from the original by calling
+// deep_copy_from. Argument use_byte_enable_on_read determines whether to use
+// or ignores byte enables when copying back the data array on a read command.
+
+void
+tlm_generic_payload::update_original_from(
+ const tlm_generic_payload &other, bool use_byte_enable_on_read)
+{
+ // Copy back extensions that are present on the original.
+ update_extensions_from(other);
+
+ // Copy back the response status and DMI hint attributes.
+ m_response_status = other.get_response_status();
+ m_dmi = other.is_dmi_allowed();
+
+ // Copy back the data array for a read command only deep_copy_from allowed
+ // null pointers, and so will we.
+ // We assume the arrays are the same size.
+ // We test for equal pointers in case the original and the copy share the
+ // same array.
+
+ if (is_read() && m_data && other.m_data && m_data != other.m_data) {
+ if (m_byte_enable && use_byte_enable_on_read) {
+ if (m_byte_enable_length == 8 && m_length % 8 == 0) {
+ // Optimized implementation copies 64-bit words by masking.
+ for (unsigned int i = 0; i < m_length; i += 8) {
+ typedef sc_dt::uint64 *u;
+ *reinterpret_cast<u>(&m_data[i]) &=
+ ~*reinterpret_cast<u>(m_byte_enable);
+ *reinterpret_cast<u>(&m_data[i]) |=
+ *reinterpret_cast<u>(&other.m_data[i]) &
+ *reinterpret_cast<u>(m_byte_enable);
+ }
+ } else if (m_byte_enable_length == 4 && m_length % 4 == 0) {
+ // Optimized implementation copies 32-bit words by masking.
+ for (unsigned int i = 0; i < m_length; i += 4) {
+ typedef unsigned int *u;
+ *reinterpret_cast<u>(&m_data[i]) &=
+ ~*reinterpret_cast<u>(m_byte_enable);
+ *reinterpret_cast<u>(&m_data[i]) |=
+ *reinterpret_cast<u>(&other.m_data[i]) &
+ *reinterpret_cast<u>(m_byte_enable);
+ }
+ } else {
+ // Unoptimized implementation.
+ for (unsigned int i = 0; i < m_length; i++) {
+ if (m_byte_enable[i % m_byte_enable_length])
+ m_data[i] = other.m_data[i];
+ }
+ }
+ } else {
+ std::memcpy(m_data, other.m_data, m_length);
+ }
+ }
+}
+
+void
+tlm_generic_payload::update_extensions_from(const tlm_generic_payload &other)
+{
+ // Deep copy extensions that are already present.
+ sc_assert(m_extensions.size() <= other.m_extensions.size());
+ for (unsigned int i = 0; i < m_extensions.size(); i++) {
+ if (other.m_extensions[i]) {
+ // Original has extension i.
+ if (m_extensions[i]) {
+ // We have it too. Copy.
+ m_extensions[i]->copy_from(*other.m_extensions[i]);
+ }
+ }
+ }
+}
+
+// Free all extensions. Useful when reusing a cloned transaction that doesn't
+// have memory manager. Normal and sticky extensions are freed and extension
+// array cleared.
+void
+tlm_generic_payload::free_all_extensions()
+{
+ m_extensions.free_entire_cache();
+ for (unsigned int i = 0; i < m_extensions.size(); i++) {
+ if (m_extensions[i]) {
+ m_extensions[i]->free();
+ m_extensions[i] = 0;
+ }
+ }
+}
+
+tlm_generic_payload::~tlm_generic_payload()
+{
+ for (unsigned int i = 0; i < m_extensions.size(); i++) {
+ if (m_extensions[i])
+ m_extensions[i]->free();
+ }
+}
+
+//----------------
+// API (including setters & getters)
+//---------------
+
+std::string
+tlm_generic_payload::get_response_string() const
+{
+ switch (m_response_status) {
+ case TLM_OK_RESPONSE:
+ return "TLM_OK_RESPONSE";
+ case TLM_INCOMPLETE_RESPONSE:
+ return "TLM_INCOMPLETE_RESPONSE";
+ case TLM_GENERIC_ERROR_RESPONSE:
+ return "TLM_GENERIC_ERROR_RESPONSE";
+ case TLM_ADDRESS_ERROR_RESPONSE:
+ return "TLM_ADDRESS_ERROR_RESPONSE";
+ case TLM_COMMAND_ERROR_RESPONSE:
+ return "TLM_COMMAND_ERROR_RESPONSE";
+ case TLM_BURST_ERROR_RESPONSE:
+ return "TLM_BURST_ERROR_RESPONSE";
+ case TLM_BYTE_ENABLE_ERROR_RESPONSE:
+ return "TLM_BYTE_ENABLE_ERROR_RESPONSE";
+ }
+ return "TLM_UNKNOWN_RESPONSE";
+}
+
+/* --------------------------------------------------------------------- */
+/* Dynamic extension mechanism: */
+/* --------------------------------------------------------------------- */
+
+tlm_extension_base *
+tlm_generic_payload::set_extension(unsigned int index, tlm_extension_base *ext)
+{
+ sc_assert(index < m_extensions.size());
+ tlm_extension_base *tmp = m_extensions[index];
+ m_extensions[index] = ext;
+ return tmp;
+}
+
+tlm_extension_base *
+tlm_generic_payload::set_auto_extension(
+ unsigned int index, tlm_extension_base *ext)
+{
+ sc_assert(index < m_extensions.size());
+ tlm_extension_base *tmp = m_extensions[index];
+ m_extensions[index] = ext;
+ if (!tmp)
+ m_extensions.insert_in_cache(&m_extensions[index]);
+ sc_assert(m_mm != 0);
+ return tmp;
+}
+
+tlm_extension_base *
+tlm_generic_payload::get_extension(unsigned int index) const
+{
+ sc_assert(index < m_extensions.size());
+ return m_extensions[index];
+}
+
+void
+tlm_generic_payload::clear_extension(unsigned int index)
+{
+ sc_assert(index < m_extensions.size());
+ m_extensions[index] = static_cast<tlm_extension_base *>(0);
+}
+
+void
+tlm_generic_payload::release_extension(unsigned int index)
+{
+ sc_assert(index < m_extensions.size());
+ if (m_mm) {
+ m_extensions.insert_in_cache(&m_extensions[index]);
+ } else {
+ m_extensions[index]->free();
+ m_extensions[index] = static_cast<tlm_extension_base *>(nullptr);
+ }
+}
+
+void
+tlm_generic_payload::resize_extensions()
+{
+ m_extensions.expand(max_num_extensions());
+}
+
+} // namespace tlm
+++ /dev/null
-/*****************************************************************************
-
- Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
- more contributor license agreements. See the NOTICE file distributed
- with this work for additional information regarding copyright ownership.
- Accellera licenses this file to you under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with the
- License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied. See the License for the specific language governing
- permissions and limitations under the License.
-
- *****************************************************************************/
-
-#include <cstring> // std::memcpy et.al.
-#include <map>
-#include <systemc>
-#include <tlm>
-
-using sc_core::sc_type_index;
-
-namespace tlm
-{
-
-template class tlm_array<tlm_extension_base *>;
-
-//---------------------------------------------------------------------------
-// Classes for the extension mechanism
-//---------------------------------------------------------------------------
-
-namespace
-{
-
-class tlm_extension_registry
-{
- typedef unsigned int key_type;
- typedef std::map<sc_core::sc_type_index, key_type> type_map;
- public:
- static tlm_extension_registry &
- instance()
- {
- if (!instance_) {
- // Don't cleanup registry.
- instance_ = new tlm_extension_registry();
- }
- return *instance_;
- }
-
- unsigned int
- register_extension(sc_type_index type)
- {
- type_map::const_iterator it = ids_.find(type);
-
- if (it == ids_.end()) {
- // New extension - generate/store ID.
- type_map::value_type v(type, static_cast<key_type>(ids_.size()));
- ids_.insert(v);
- return v.second;
- }
- return it->second;
- }
-
- static unsigned int
- max_num_extensions()
- {
- return (instance_) ? instance().ids_.size() : 0;
- }
-
- private:
- static tlm_extension_registry *instance_;
- type_map ids_;
- tlm_extension_registry() {}
-
-};
-
-tlm_extension_registry *tlm_extension_registry::instance_ = NULL;
-
-} // anonymous namespace
-
-unsigned int
-max_num_extensions()
-{
- return tlm_extension_registry::max_num_extensions();
-}
-
-unsigned int
-tlm_extension_base::register_extension(const std::type_info &type)
-{
- return tlm_extension_registry::instance().register_extension(type);
-}
-
-//---------------------------------------------------------------------------
-// The generic payload class:
-//---------------------------------------------------------------------------
-
-tlm_generic_payload::tlm_generic_payload() : m_address(0),
- m_command(TLM_IGNORE_COMMAND), m_data(0), m_length(0),
- m_response_status(TLM_INCOMPLETE_RESPONSE), m_dmi(false), m_byte_enable(0),
- m_byte_enable_length(0), m_streaming_width(0),
- m_gp_option(TLM_MIN_PAYLOAD), m_extensions(max_num_extensions()), m_mm(0),
- m_ref_count(0)
-{}
-
-tlm_generic_payload::tlm_generic_payload(tlm_mm_interface *mm): m_address(0),
- m_command(TLM_IGNORE_COMMAND), m_data(0), m_length(0),
- m_response_status(TLM_INCOMPLETE_RESPONSE), m_dmi(false), m_byte_enable(0),
- m_byte_enable_length(0), m_streaming_width(0),
- m_gp_option(TLM_MIN_PAYLOAD), m_extensions(max_num_extensions()), m_mm(mm),
- m_ref_count(0)
-{}
-
-void
-tlm_generic_payload::reset()
-{
- // Should the other members be reset too?
- m_gp_option = TLM_MIN_PAYLOAD;
- m_extensions.free_entire_cache();
-};
-
-// Non-virtual deep-copying of the object.
-void
-tlm_generic_payload::deep_copy_from(const tlm_generic_payload &other)
-{
- m_command = other.get_command();
- m_address = other.get_address();
- m_length = other.get_data_length();
- m_response_status = other.get_response_status();
- m_byte_enable_length = other.get_byte_enable_length();
- m_streaming_width = other.get_streaming_width();
- m_gp_option = other.get_gp_option();
- m_dmi = other.is_dmi_allowed();
-
- // Deep copy data.
- // There must be enough space in the target transaction!
- if (m_data && other.m_data) {
- std::memcpy(m_data, other.m_data, m_length);
- }
- // Deep copy byte enables.
- // There must be enough space in the target transaction!
- if (m_byte_enable && other.m_byte_enable) {
- std::memcpy(m_byte_enable, other.m_byte_enable, m_byte_enable_length);
- }
- // Deep copy extensions (sticky and non-sticky).
- if (m_extensions.size() < other.m_extensions.size()) {
- m_extensions.expand(other.m_extensions.size());
- }
- for (unsigned int i = 0; i < other.m_extensions.size(); i++) {
- if (other.m_extensions[i]) {
- // Original has extension i.
- if (!m_extensions[i]) {
- // We don't: clone.
- tlm_extension_base *ext = other.m_extensions[i]->clone();
- if (ext) { // Extension may not be clonable.
- if (has_mm()) {
- // mm can take care of removing cloned extensions.
- set_auto_extension(i, ext);
- } else {
- // no mm, user will call free_all_extensions().
- set_extension(i, ext);
- }
- }
- } else {
- // We already have such extension. Copy original over it.
- m_extensions[i]->copy_from(*other.m_extensions[i]);
- }
- }
- }
-}
-
-// To update the state of the original generic payload from a deep copy.
-// Assumes that "other" was created from the original by calling
-// deep_copy_from. Argument use_byte_enable_on_read determines whether to use
-// or ignores byte enables when copying back the data array on a read command.
-
-void
-tlm_generic_payload::update_original_from(
- const tlm_generic_payload &other, bool use_byte_enable_on_read)
-{
- // Copy back extensions that are present on the original.
- update_extensions_from(other);
-
- // Copy back the response status and DMI hint attributes.
- m_response_status = other.get_response_status();
- m_dmi = other.is_dmi_allowed();
-
- // Copy back the data array for a read command only deep_copy_from allowed
- // null pointers, and so will we.
- // We assume the arrays are the same size.
- // We test for equal pointers in case the original and the copy share the
- // same array.
-
- if (is_read() && m_data && other.m_data && m_data != other.m_data) {
- if (m_byte_enable && use_byte_enable_on_read) {
- if (m_byte_enable_length == 8 && m_length % 8 == 0) {
- // Optimized implementation copies 64-bit words by masking.
- for (unsigned int i = 0; i < m_length; i += 8) {
- typedef sc_dt::uint64 *u;
- *reinterpret_cast<u>(&m_data[i]) &=
- ~*reinterpret_cast<u>(m_byte_enable);
- *reinterpret_cast<u>(&m_data[i]) |=
- *reinterpret_cast<u>(&other.m_data[i]) &
- *reinterpret_cast<u>(m_byte_enable);
- }
- } else if (m_byte_enable_length == 4 && m_length % 4 == 0) {
- // Optimized implementation copies 32-bit words by masking.
- for (unsigned int i = 0; i < m_length; i += 4) {
- typedef unsigned int *u;
- *reinterpret_cast<u>(&m_data[i]) &=
- ~*reinterpret_cast<u>(m_byte_enable);
- *reinterpret_cast<u>(&m_data[i]) |=
- *reinterpret_cast<u>(&other.m_data[i]) &
- *reinterpret_cast<u>(m_byte_enable);
- }
- } else {
- // Unoptimized implementation.
- for (unsigned int i = 0; i < m_length; i++) {
- if (m_byte_enable[i % m_byte_enable_length])
- m_data[i] = other.m_data[i];
- }
- }
- } else {
- std::memcpy(m_data, other.m_data, m_length);
- }
- }
-}
-
-void
-tlm_generic_payload::update_extensions_from(const tlm_generic_payload &other)
-{
- // Deep copy extensions that are already present.
- sc_assert(m_extensions.size() <= other.m_extensions.size());
- for (unsigned int i = 0; i < m_extensions.size(); i++) {
- if (other.m_extensions[i]) {
- // Original has extension i.
- if (m_extensions[i]) {
- // We have it too. Copy.
- m_extensions[i]->copy_from(*other.m_extensions[i]);
- }
- }
- }
-}
-
-// Free all extensions. Useful when reusing a cloned transaction that doesn't
-// have memory manager. Normal and sticky extensions are freed and extension
-// array cleared.
-void
-tlm_generic_payload::free_all_extensions()
-{
- m_extensions.free_entire_cache();
- for (unsigned int i = 0; i < m_extensions.size(); i++) {
- if (m_extensions[i]) {
- m_extensions[i]->free();
- m_extensions[i] = 0;
- }
- }
-}
-
-tlm_generic_payload::~tlm_generic_payload()
-{
- for (unsigned int i = 0; i < m_extensions.size(); i++) {
- if (m_extensions[i])
- m_extensions[i]->free();
- }
-}
-
-//----------------
-// API (including setters & getters)
-//---------------
-
-std::string
-tlm_generic_payload::get_response_string() const
-{
- switch (m_response_status) {
- case TLM_OK_RESPONSE:
- return "TLM_OK_RESPONSE";
- case TLM_INCOMPLETE_RESPONSE:
- return "TLM_INCOMPLETE_RESPONSE";
- case TLM_GENERIC_ERROR_RESPONSE:
- return "TLM_GENERIC_ERROR_RESPONSE";
- case TLM_ADDRESS_ERROR_RESPONSE:
- return "TLM_ADDRESS_ERROR_RESPONSE";
- case TLM_COMMAND_ERROR_RESPONSE:
- return "TLM_COMMAND_ERROR_RESPONSE";
- case TLM_BURST_ERROR_RESPONSE:
- return "TLM_BURST_ERROR_RESPONSE";
- case TLM_BYTE_ENABLE_ERROR_RESPONSE:
- return "TLM_BYTE_ENABLE_ERROR_RESPONSE";
- }
- return "TLM_UNKNOWN_RESPONSE";
-}
-
-/* --------------------------------------------------------------------- */
-/* Dynamic extension mechanism: */
-/* --------------------------------------------------------------------- */
-
-tlm_extension_base *
-tlm_generic_payload::set_extension(unsigned int index, tlm_extension_base *ext)
-{
- sc_assert(index < m_extensions.size());
- tlm_extension_base *tmp = m_extensions[index];
- m_extensions[index] = ext;
- return tmp;
-}
-
-tlm_extension_base *
-tlm_generic_payload::set_auto_extension(
- unsigned int index, tlm_extension_base *ext)
-{
- sc_assert(index < m_extensions.size());
- tlm_extension_base *tmp = m_extensions[index];
- m_extensions[index] = ext;
- if (!tmp)
- m_extensions.insert_in_cache(&m_extensions[index]);
- sc_assert(m_mm != 0);
- return tmp;
-}
-
-tlm_extension_base *
-tlm_generic_payload::get_extension(unsigned int index) const
-{
- sc_assert(index < m_extensions.size());
- return m_extensions[index];
-}
-
-void
-tlm_generic_payload::clear_extension(unsigned int index)
-{
- sc_assert(index < m_extensions.size());
- m_extensions[index] = static_cast<tlm_extension_base *>(0);
-}
-
-void
-tlm_generic_payload::release_extension(unsigned int index)
-{
- sc_assert(index < m_extensions.size());
- if (m_mm) {
- m_extensions.insert_in_cache(&m_extensions[index]);
- } else {
- m_extensions[index]->free();
- m_extensions[index] = static_cast<tlm_extension_base *>(nullptr);
- }
-}
-
-void
-tlm_generic_payload::resize_extensions()
-{
- m_extensions.expand(max_num_extensions());
-}
-
-} // namespace tlm
--- /dev/null
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+#include <cstring>
+#include <map>
+#include <systemc>
+#include <tlm>
+
+using sc_core::sc_string_view;
+using sc_core::sc_type_index;
+
+namespace tlm
+{
+
+namespace
+{
+
+struct tlm_phase_registry
+{
+ typedef unsigned int key_type;
+
+ static tlm_phase_registry &
+ instance()
+ {
+ static tlm_phase_registry inst;
+ return inst;
+ }
+
+ unsigned int
+ register_phase(sc_type_index type, sc_string_view name)
+ {
+ type_map::const_iterator it = ids_.find(type);
+
+ if (name.empty()) {
+ SC_REPORT_FATAL( sc_core::SC_ID_INTERNAL_ERROR_,
+ "unexpected empty tlm_phase name" );
+ return UNINITIALIZED_PHASE;
+ }
+
+ if (it == ids_.end()) {
+ // new phase - generate/store ID and name
+ type_map::value_type v(type, static_cast<key_type>(names_.size()));
+ names_.push_back(name_table::value_type(name.data(), name.size()));
+ ids_.insert(v);
+ return v.second;
+ }
+
+ if (names_[it->second] != name) {
+ SC_REPORT_FATAL(sc_core::SC_ID_INTERNAL_ERROR_,
+ "tlm_phase registration failed: duplicate type info" );
+ sc_core::sc_abort();
+ }
+ return it->second;
+ }
+
+ const char *
+ get_name(key_type id) const
+ {
+ sc_assert(id < names_.size());
+ return names_[id].c_str();
+ }
+
+ private:
+ typedef std::map<sc_type_index, key_type> type_map;
+ typedef std::vector<std::string> name_table;
+
+ type_map ids_;
+ name_table names_;
+
+ tlm_phase_registry() : names_(END_RESP + 1)
+ {
+ names_[UNINITIALIZED_PHASE] = "UNINITIALIZED_PHASE";
+ names_[BEGIN_REQ] = "BEGIN_REQ";
+ names_[END_REQ] = "END_REQ";
+ names_[BEGIN_RESP] = "BEGIN_RESP";
+ names_[END_RESP] = "END_RESP";
+ }
+};
+
+} // anonymous namespace
+
+tlm_phase::tlm_phase(unsigned int id) : m_id(id)
+{}
+
+tlm_phase::tlm_phase(const std::type_info &type, const char *name) :
+ m_id(tlm_phase_registry::instance().register_phase(type, name))
+{}
+
+const char *
+tlm_phase::get_name() const
+{
+ return tlm_phase_registry::instance().get_name(m_id);
+}
+
+} // namespace tlm
+++ /dev/null
-/*****************************************************************************
-
- Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
- more contributor license agreements. See the NOTICE file distributed
- with this work for additional information regarding copyright ownership.
- Accellera licenses this file to you under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with the
- License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied. See the License for the specific language governing
- permissions and limitations under the License.
-
- *****************************************************************************/
-
-#include <cstring>
-#include <map>
-#include <systemc>
-#include <tlm>
-
-using sc_core::sc_string_view;
-using sc_core::sc_type_index;
-
-namespace tlm
-{
-
-namespace
-{
-
-struct tlm_phase_registry
-{
- typedef unsigned int key_type;
-
- static tlm_phase_registry &
- instance()
- {
- static tlm_phase_registry inst;
- return inst;
- }
-
- unsigned int
- register_phase(sc_type_index type, sc_string_view name)
- {
- type_map::const_iterator it = ids_.find(type);
-
- if (name.empty()) {
- SC_REPORT_FATAL( sc_core::SC_ID_INTERNAL_ERROR_,
- "unexpected empty tlm_phase name" );
- return UNINITIALIZED_PHASE;
- }
-
- if (it == ids_.end()) {
- // new phase - generate/store ID and name
- type_map::value_type v(type, static_cast<key_type>(names_.size()));
- names_.push_back(name_table::value_type(name.data(), name.size()));
- ids_.insert(v);
- return v.second;
- }
-
- if (names_[it->second] != name) {
- SC_REPORT_FATAL(sc_core::SC_ID_INTERNAL_ERROR_,
- "tlm_phase registration failed: duplicate type info" );
- sc_core::sc_abort();
- }
- return it->second;
- }
-
- const char *
- get_name(key_type id) const
- {
- sc_assert(id < names_.size());
- return names_[id].c_str();
- }
-
- private:
- typedef std::map<sc_type_index, key_type> type_map;
- typedef std::vector<std::string> name_table;
-
- type_map ids_;
- name_table names_;
-
- tlm_phase_registry() : names_(END_RESP + 1)
- {
- names_[UNINITIALIZED_PHASE] = "UNINITIALIZED_PHASE";
- names_[BEGIN_REQ] = "BEGIN_REQ";
- names_[END_REQ] = "END_REQ";
- names_[BEGIN_RESP] = "BEGIN_RESP";
- names_[END_RESP] = "END_RESP";
- }
-};
-
-} // anonymous namespace
-
-tlm_phase::tlm_phase(unsigned int id) : m_id(id)
-{}
-
-tlm_phase::tlm_phase(const std::type_info &type, const char *name) :
- m_id(tlm_phase_registry::instance().register_phase(type, name))
-{}
-
-const char *
-tlm_phase::get_name() const
-{
- return tlm_phase_registry::instance().get_name(m_id);
-}
-
-} // namespace tlm
--- /dev/null
+# Copyright 2018 Google, Inc.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# Authors: Gabe Black
+
+Import('*')
+
+if env['USE_SYSTEMC']:
+ Source('tlm_global_quantum.cc')
--- /dev/null
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+#include <systemc>
+#include <tlm>
+
+namespace tlm
+{
+
+tlm_global_quantum::tlm_global_quantum() :
+ m_global_quantum(sc_core::SC_ZERO_TIME)
+{}
+
+tlm_global_quantum &
+tlm_global_quantum::instance()
+{
+ static tlm_global_quantum instance_;
+ return instance_;
+}
+
+sc_core::sc_time
+tlm_global_quantum::compute_local_quantum()
+{
+ if (m_global_quantum != sc_core::SC_ZERO_TIME) {
+ const sc_core::sc_time current = sc_core::sc_time_stamp();
+ const sc_core::sc_time g_quant = m_global_quantum;
+ return g_quant - (current % g_quant);
+ } else {
+ return sc_core::SC_ZERO_TIME;
+ }
+}
+
+} // namespace tlm
+++ /dev/null
-/*****************************************************************************
-
- Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
- more contributor license agreements. See the NOTICE file distributed
- with this work for additional information regarding copyright ownership.
- Accellera licenses this file to you under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with the
- License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied. See the License for the specific language governing
- permissions and limitations under the License.
-
- *****************************************************************************/
-
-#include <systemc>
-#include <tlm>
-
-namespace tlm
-{
-
-tlm_global_quantum::tlm_global_quantum() :
- m_global_quantum(sc_core::SC_ZERO_TIME)
-{}
-
-tlm_global_quantum &
-tlm_global_quantum::instance()
-{
- static tlm_global_quantum instance_;
- return instance_;
-}
-
-sc_core::sc_time
-tlm_global_quantum::compute_local_quantum()
-{
- if (m_global_quantum != sc_core::SC_ZERO_TIME) {
- const sc_core::sc_time current = sc_core::sc_time_stamp();
- const sc_core::sc_time g_quant = m_global_quantum;
- return g_quant - (current % g_quant);
- } else {
- return sc_core::SC_ZERO_TIME;
- }
-}
-
-} // namespace tlm
--- /dev/null
+# Copyright 2018 Google, Inc.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# Authors: Gabe Black
+
+Import('*')
+
+if env['USE_SYSTEMC']:
+ Source('convenience_socket_bases.cc')
+ Source('instance_specific_extensions.cc')
--- /dev/null
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+#include <tlm_utils/convenience_socket_bases.h>
+
+#include <sstream>
+#include <systemc>
+
+namespace tlm_utils
+{
+
+void
+convenience_socket_base::display_warning(const char *text) const
+{
+ std::stringstream s;
+ s << get_socket()->name() << ": " << text;
+ SC_REPORT_WARNING(get_report_type(), s.str().c_str());
+}
+
+void
+convenience_socket_base::display_error(const char *text) const
+{
+ std::stringstream s;
+ s << get_socket()->name() << ": " << text;
+ SC_REPORT_ERROR(get_report_type(), s.str().c_str());
+}
+
+// Simple helpers for warnings an errors to shorten in code notation.
+
+void
+convenience_socket_cb_holder::display_warning(const char *msg) const
+{
+ m_owner->display_warning(msg);
+}
+
+void
+convenience_socket_cb_holder::display_error(const char *msg) const
+{
+ m_owner->display_error(msg);
+}
+
+const char *
+simple_socket_base::get_report_type() const
+{
+ return "/OSCI_TLM-2/simple_socket";
+}
+
+void
+simple_socket_base::elaboration_check(const char *action) const
+{
+ if (sc_core::sc_get_curr_simcontext()->elaboration_done()) {
+ std::stringstream s;
+ s << " elaboration completed, " << action << " not allowed";
+ display_error(s.str().c_str());
+ }
+}
+
+const char *
+passthrough_socket_base::get_report_type() const
+{
+ return "/OSCI_TLM-2/passthrough_socket";
+}
+
+const char *
+multi_socket_base::get_report_type() const
+{
+ return "/OSCI_TLM-2/multi_socket";
+}
+
+} // namespace tlm_utils
+++ /dev/null
-/*****************************************************************************
-
- Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
- more contributor license agreements. See the NOTICE file distributed
- with this work for additional information regarding copyright ownership.
- Accellera licenses this file to you under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with the
- License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied. See the License for the specific language governing
- permissions and limitations under the License.
-
- *****************************************************************************/
-
-#include <tlm_utils/convenience_socket_bases.h>
-
-#include <sstream>
-#include <systemc>
-
-namespace tlm_utils
-{
-
-void
-convenience_socket_base::display_warning(const char *text) const
-{
- std::stringstream s;
- s << get_socket()->name() << ": " << text;
- SC_REPORT_WARNING(get_report_type(), s.str().c_str());
-}
-
-void
-convenience_socket_base::display_error(const char *text) const
-{
- std::stringstream s;
- s << get_socket()->name() << ": " << text;
- SC_REPORT_ERROR(get_report_type(), s.str().c_str());
-}
-
-// Simple helpers for warnings an errors to shorten in code notation.
-
-void
-convenience_socket_cb_holder::display_warning(const char *msg) const
-{
- m_owner->display_warning(msg);
-}
-
-void
-convenience_socket_cb_holder::display_error(const char *msg) const
-{
- m_owner->display_error(msg);
-}
-
-const char *
-simple_socket_base::get_report_type() const
-{
- return "/OSCI_TLM-2/simple_socket";
-}
-
-void
-simple_socket_base::elaboration_check(const char *action) const
-{
- if (sc_core::sc_get_curr_simcontext()->elaboration_done()) {
- std::stringstream s;
- s << " elaboration completed, " << action << " not allowed";
- display_error(s.str().c_str());
- }
-}
-
-const char *
-passthrough_socket_base::get_report_type() const
-{
- return "/OSCI_TLM-2/passthrough_socket";
-}
-
-const char *
-multi_socket_base::get_report_type() const
-{
- return "/OSCI_TLM-2/multi_socket";
-}
-
-} // namespace tlm_utils
--- /dev/null
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+#include <tlm_utils/instance_specific_extensions_int.h>
+
+#include <iostream>
+#include <map>
+#include <systemc>
+#include <tlm>
+
+namespace tlm
+{
+
+template class tlm_array<tlm_utils::ispex_base *>;
+
+} // namespace tlm
+
+namespace tlm_utils
+{
+
+namespace
+{
+
+class ispex_registry // Copied from tlm_gp.cpp.
+{
+ typedef unsigned int key_type;
+ typedef std::map<sc_core::sc_type_index, key_type> type_map;
+
+ public:
+ static ispex_registry &
+ instance()
+ {
+ if (!instance_) {
+ // Don't cleanup registry.
+ instance_ = new ispex_registry();
+ }
+ return *instance_;
+ }
+
+ unsigned int
+ register_extension(sc_core::sc_type_index type)
+ {
+ type_map::const_iterator it = ids_.find(type);
+
+ if (it == ids_.end()) {
+ // New extension - generate/store ID.
+ type_map::value_type v(type, static_cast<key_type>(ids_.size()));
+ ids_.insert(v);
+ return v.second;
+ }
+ return it->second;
+ }
+
+ static unsigned int
+ max_num_extensions()
+ {
+ return (instance_) ? instance().ids_.size() : 0;
+ }
+
+ private:
+ static ispex_registry *instance_;
+ type_map ids_;
+ ispex_registry() {}
+};
+
+ispex_registry *ispex_registry::instance_ = nullptr;
+
+} // anonymous namespace
+
+unsigned int
+ispex_base::register_private_extension(const std::type_info &type)
+{
+ return ispex_registry::instance().register_extension(type);
+}
+
+// Helper to do the numbering of private extension accessors.
+static unsigned int
+max_num_ispex_accessors(bool increment=false)
+{
+ static unsigned int max_num = 0;
+ if (increment)
+ ++max_num;
+ return max_num;
+}
+
+// ----------------------------------------------------------------------------
+
+// The pool for the container, plain as can be.
+class instance_specific_extension_container_pool
+{
+ instance_specific_extension_container_pool() : unused(nullptr) {}
+ ~instance_specific_extension_container_pool();
+
+ public:
+ static instance_specific_extension_container_pool &
+ instance()
+ {
+ static instance_specific_extension_container_pool inst;
+ return inst;
+ }
+
+ instance_specific_extension_container *create();
+ void free(instance_specific_extension_container *);
+
+ private:
+ instance_specific_extension_container *unused;
+};
+
+instance_specific_extension_container *
+instance_specific_extension_container_pool::create()
+{
+ if (!unused) {
+ unused = new instance_specific_extension_container();
+ }
+ instance_specific_extension_container *tmp = unused;
+ unused = unused->next;
+ return tmp;
+}
+
+void
+instance_specific_extension_container_pool::free(
+ instance_specific_extension_container *cont)
+{
+ cont->next = unused;
+ unused = cont;
+}
+
+instance_specific_extension_container_pool::
+ ~instance_specific_extension_container_pool()
+{
+ while (unused) {
+ instance_specific_extension_container *tmp = unused;
+ unused = unused->next;
+ delete tmp;
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+instance_specific_extension_container *
+instance_specific_extension_container::create()
+{
+ return instance_specific_extension_container_pool::instance().create();
+}
+
+instance_specific_extension_container::
+ instance_specific_extension_container() :
+ use_count(0), m_txn(NULL), m_release_fn(NULL), m_carrier(NULL), next(NULL)
+{
+ resize();
+}
+
+void
+instance_specific_extension_container::
+ attach_carrier(instance_specific_extension_carrier *carrier,
+ void *txn, release_fn *rel_fn)
+{
+ m_txn = txn;
+ m_release_fn = rel_fn;
+ m_carrier = carrier;
+}
+
+void
+instance_specific_extension_container::resize()
+{
+ m_ispex_per_accessor.resize(max_num_ispex_accessors());
+
+ for (unsigned int i = 0; i < m_ispex_per_accessor.size(); ++i) {
+ m_ispex_per_accessor[i] =
+ new instance_specific_extensions_per_accessor(this);
+ m_ispex_per_accessor[i]->resize_extensions();
+ }
+}
+
+instance_specific_extension_container::
+ ~instance_specific_extension_container()
+{
+ for (unsigned int i = 0; i < m_ispex_per_accessor.size(); ++i)
+ delete m_ispex_per_accessor[i];
+}
+
+void
+instance_specific_extension_container::inc_use_count()
+{
+ use_count++;
+}
+
+void
+instance_specific_extension_container::dec_use_count()
+{
+ if ((--use_count) == 0) {
+ // If this container isn't used any more we release the carrier
+ // extension.
+ m_release_fn(m_carrier, m_txn);
+ // We send it back to our pool.
+ instance_specific_extension_container_pool::instance().free(this);
+ }
+}
+
+instance_specific_extensions_per_accessor *
+instance_specific_extension_container::get_accessor(unsigned int idx)
+{
+ return m_ispex_per_accessor[idx];
+}
+
+// ----------------------------------------------------------------------------
+
+// non-templatized version with manual index:
+ispex_base *
+instance_specific_extensions_per_accessor::set_extension(
+ unsigned int index, ispex_base *ext)
+{
+ resize_extensions();
+ ispex_base *tmp = m_extensions[index];
+ m_extensions[index] = ext;
+ if (!tmp && ext)
+ m_container->inc_use_count();
+ return tmp;
+}
+
+ispex_base *
+instance_specific_extensions_per_accessor::get_extension(
+ unsigned int index) const
+{
+ return (index < m_extensions.size()) ? m_extensions[index] : nullptr;
+}
+
+void
+instance_specific_extensions_per_accessor::clear_extension(unsigned int index)
+{
+ if (index < m_extensions.size()) {
+ if (m_extensions[index])
+ m_container->dec_use_count();
+ m_extensions[index] = static_cast<ispex_base *>(nullptr);
+ }
+}
+
+void
+instance_specific_extensions_per_accessor::resize_extensions()
+{
+ m_extensions.expand(ispex_registry::max_num_extensions());
+}
+
+// ----------------------------------------------------------------------------
+
+instance_specific_extension_accessor::instance_specific_extension_accessor() :
+ m_index(max_num_ispex_accessors(true) - 1)
+{}
+
+} // namespace tlm_utils
+++ /dev/null
-/*****************************************************************************
-
- Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
- more contributor license agreements. See the NOTICE file distributed
- with this work for additional information regarding copyright ownership.
- Accellera licenses this file to you under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with the
- License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied. See the License for the specific language governing
- permissions and limitations under the License.
-
- *****************************************************************************/
-
-#include <tlm_utils/instance_specific_extensions_int.h>
-
-#include <iostream>
-#include <map>
-#include <systemc>
-#include <tlm>
-
-namespace tlm
-{
-
-template class tlm_array<tlm_utils::ispex_base *>;
-
-} // namespace tlm
-
-namespace tlm_utils
-{
-
-namespace
-{
-
-class ispex_registry // Copied from tlm_gp.cpp.
-{
- typedef unsigned int key_type;
- typedef std::map<sc_core::sc_type_index, key_type> type_map;
-
- public:
- static ispex_registry &
- instance()
- {
- if (!instance_) {
- // Don't cleanup registry.
- instance_ = new ispex_registry();
- }
- return *instance_;
- }
-
- unsigned int
- register_extension(sc_core::sc_type_index type)
- {
- type_map::const_iterator it = ids_.find(type);
-
- if (it == ids_.end()) {
- // New extension - generate/store ID.
- type_map::value_type v(type, static_cast<key_type>(ids_.size()));
- ids_.insert(v);
- return v.second;
- }
- return it->second;
- }
-
- static unsigned int
- max_num_extensions()
- {
- return (instance_) ? instance().ids_.size() : 0;
- }
-
- private:
- static ispex_registry *instance_;
- type_map ids_;
- ispex_registry() {}
-};
-
-ispex_registry *ispex_registry::instance_ = nullptr;
-
-} // anonymous namespace
-
-unsigned int
-ispex_base::register_private_extension(const std::type_info &type)
-{
- return ispex_registry::instance().register_extension(type);
-}
-
-// Helper to do the numbering of private extension accessors.
-static unsigned int
-max_num_ispex_accessors(bool increment=false)
-{
- static unsigned int max_num = 0;
- if (increment)
- ++max_num;
- return max_num;
-}
-
-// ----------------------------------------------------------------------------
-
-// The pool for the container, plain as can be.
-class instance_specific_extension_container_pool
-{
- instance_specific_extension_container_pool() : unused(nullptr) {}
- ~instance_specific_extension_container_pool();
-
- public:
- static instance_specific_extension_container_pool &
- instance()
- {
- static instance_specific_extension_container_pool inst;
- return inst;
- }
-
- instance_specific_extension_container *create();
- void free(instance_specific_extension_container *);
-
- private:
- instance_specific_extension_container *unused;
-};
-
-instance_specific_extension_container *
-instance_specific_extension_container_pool::create()
-{
- if (!unused) {
- unused = new instance_specific_extension_container();
- }
- instance_specific_extension_container *tmp = unused;
- unused = unused->next;
- return tmp;
-}
-
-void
-instance_specific_extension_container_pool::free(
- instance_specific_extension_container *cont)
-{
- cont->next = unused;
- unused = cont;
-}
-
-instance_specific_extension_container_pool::
- ~instance_specific_extension_container_pool()
-{
- while (unused) {
- instance_specific_extension_container *tmp = unused;
- unused = unused->next;
- delete tmp;
- }
-}
-
-// ----------------------------------------------------------------------------
-
-instance_specific_extension_container *
-instance_specific_extension_container::create()
-{
- return instance_specific_extension_container_pool::instance().create();
-}
-
-instance_specific_extension_container::
- instance_specific_extension_container() :
- use_count(0), m_txn(NULL), m_release_fn(NULL), m_carrier(NULL), next(NULL)
-{
- resize();
-}
-
-void
-instance_specific_extension_container::
- attach_carrier(instance_specific_extension_carrier *carrier,
- void *txn, release_fn *rel_fn)
-{
- m_txn = txn;
- m_release_fn = rel_fn;
- m_carrier = carrier;
-}
-
-void
-instance_specific_extension_container::resize()
-{
- m_ispex_per_accessor.resize(max_num_ispex_accessors());
-
- for (unsigned int i = 0; i < m_ispex_per_accessor.size(); ++i) {
- m_ispex_per_accessor[i] =
- new instance_specific_extensions_per_accessor(this);
- m_ispex_per_accessor[i]->resize_extensions();
- }
-}
-
-instance_specific_extension_container::
- ~instance_specific_extension_container()
-{
- for (unsigned int i = 0; i < m_ispex_per_accessor.size(); ++i)
- delete m_ispex_per_accessor[i];
-}
-
-void
-instance_specific_extension_container::inc_use_count()
-{
- use_count++;
-}
-
-void
-instance_specific_extension_container::dec_use_count()
-{
- if ((--use_count) == 0) {
- // If this container isn't used any more we release the carrier
- // extension.
- m_release_fn(m_carrier, m_txn);
- // We send it back to our pool.
- instance_specific_extension_container_pool::instance().free(this);
- }
-}
-
-instance_specific_extensions_per_accessor *
-instance_specific_extension_container::get_accessor(unsigned int idx)
-{
- return m_ispex_per_accessor[idx];
-}
-
-// ----------------------------------------------------------------------------
-
-// non-templatized version with manual index:
-ispex_base *
-instance_specific_extensions_per_accessor::set_extension(
- unsigned int index, ispex_base *ext)
-{
- resize_extensions();
- ispex_base *tmp = m_extensions[index];
- m_extensions[index] = ext;
- if (!tmp && ext)
- m_container->inc_use_count();
- return tmp;
-}
-
-ispex_base *
-instance_specific_extensions_per_accessor::get_extension(
- unsigned int index) const
-{
- return (index < m_extensions.size()) ? m_extensions[index] : nullptr;
-}
-
-void
-instance_specific_extensions_per_accessor::clear_extension(unsigned int index)
-{
- if (index < m_extensions.size()) {
- if (m_extensions[index])
- m_container->dec_use_count();
- m_extensions[index] = static_cast<ispex_base *>(nullptr);
- }
-}
-
-void
-instance_specific_extensions_per_accessor::resize_extensions()
-{
- m_extensions.expand(ispex_registry::max_num_extensions());
-}
-
-// ----------------------------------------------------------------------------
-
-instance_specific_extension_accessor::instance_specific_extension_accessor() :
- m_index(max_num_ispex_accessors(true) - 1)
-{}
-
-} // namespace tlm_utils