From 77165ae17ffa3c93b333e52e633b6237b1aca996 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 2 Jan 2019 21:16:38 -0800 Subject: systemc: Rename tlm .cpp files to .cc and add SConscripts. Change-Id: Ia30192b441dd34bc7165c6335386c88c0015fdf6 Reviewed-on: https://gem5-review.googlesource.com/c/15295 Reviewed-by: Anthony Gutierrez Maintainer: Anthony Gutierrez --- .../tlm_core/tlm_2/tlm_generic_payload/SConscript | 32 ++ .../tlm_core/tlm_2/tlm_generic_payload/tlm_gp.cc | 355 +++++++++++++++++++++ .../tlm_core/tlm_2/tlm_generic_payload/tlm_gp.cpp | 355 --------------------- .../tlm_2/tlm_generic_payload/tlm_phase.cc | 111 +++++++ .../tlm_2/tlm_generic_payload/tlm_phase.cpp | 111 ------- src/systemc/tlm_core/tlm_2/tlm_quantum/SConscript | 31 ++ .../tlm_2/tlm_quantum/tlm_global_quantum.cc | 49 +++ .../tlm_2/tlm_quantum/tlm_global_quantum.cpp | 49 --- src/systemc/tlm_utils/SConscript | 32 ++ src/systemc/tlm_utils/convenience_socket_bases.cc | 86 +++++ src/systemc/tlm_utils/convenience_socket_bases.cpp | 86 ----- .../tlm_utils/instance_specific_extensions.cc | 266 +++++++++++++++ .../tlm_utils/instance_specific_extensions.cpp | 266 --------------- 13 files changed, 962 insertions(+), 867 deletions(-) create mode 100644 src/systemc/tlm_core/tlm_2/tlm_generic_payload/SConscript create mode 100644 src/systemc/tlm_core/tlm_2/tlm_generic_payload/tlm_gp.cc delete mode 100644 src/systemc/tlm_core/tlm_2/tlm_generic_payload/tlm_gp.cpp create mode 100644 src/systemc/tlm_core/tlm_2/tlm_generic_payload/tlm_phase.cc delete mode 100644 src/systemc/tlm_core/tlm_2/tlm_generic_payload/tlm_phase.cpp create mode 100644 src/systemc/tlm_core/tlm_2/tlm_quantum/SConscript create mode 100644 src/systemc/tlm_core/tlm_2/tlm_quantum/tlm_global_quantum.cc delete mode 100644 src/systemc/tlm_core/tlm_2/tlm_quantum/tlm_global_quantum.cpp create mode 100644 src/systemc/tlm_utils/SConscript create mode 100644 src/systemc/tlm_utils/convenience_socket_bases.cc delete mode 100644 src/systemc/tlm_utils/convenience_socket_bases.cpp create mode 100644 src/systemc/tlm_utils/instance_specific_extensions.cc delete mode 100644 src/systemc/tlm_utils/instance_specific_extensions.cpp diff --git a/src/systemc/tlm_core/tlm_2/tlm_generic_payload/SConscript b/src/systemc/tlm_core/tlm_2/tlm_generic_payload/SConscript new file mode 100644 index 000000000..0d6557931 --- /dev/null +++ b/src/systemc/tlm_core/tlm_2/tlm_generic_payload/SConscript @@ -0,0 +1,32 @@ +# 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') diff --git a/src/systemc/tlm_core/tlm_2/tlm_generic_payload/tlm_gp.cc b/src/systemc/tlm_core/tlm_2/tlm_generic_payload/tlm_gp.cc new file mode 100644 index 000000000..ff3c92bd9 --- /dev/null +++ b/src/systemc/tlm_core/tlm_2/tlm_generic_payload/tlm_gp.cc @@ -0,0 +1,355 @@ +/***************************************************************************** + + 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 // std::memcpy et.al. +#include +#include +#include + +using sc_core::sc_type_index; + +namespace tlm +{ + +template class tlm_array; + +//--------------------------------------------------------------------------- +// Classes for the extension mechanism +//--------------------------------------------------------------------------- + +namespace +{ + +class tlm_extension_registry +{ + typedef unsigned int key_type; + typedef std::map 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(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(&m_data[i]) &= + ~*reinterpret_cast(m_byte_enable); + *reinterpret_cast(&m_data[i]) |= + *reinterpret_cast(&other.m_data[i]) & + *reinterpret_cast(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(&m_data[i]) &= + ~*reinterpret_cast(m_byte_enable); + *reinterpret_cast(&m_data[i]) |= + *reinterpret_cast(&other.m_data[i]) & + *reinterpret_cast(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(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(nullptr); + } +} + +void +tlm_generic_payload::resize_extensions() +{ + m_extensions.expand(max_num_extensions()); +} + +} // namespace tlm diff --git a/src/systemc/tlm_core/tlm_2/tlm_generic_payload/tlm_gp.cpp b/src/systemc/tlm_core/tlm_2/tlm_generic_payload/tlm_gp.cpp deleted file mode 100644 index ff3c92bd9..000000000 --- a/src/systemc/tlm_core/tlm_2/tlm_generic_payload/tlm_gp.cpp +++ /dev/null @@ -1,355 +0,0 @@ -/***************************************************************************** - - 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 // std::memcpy et.al. -#include -#include -#include - -using sc_core::sc_type_index; - -namespace tlm -{ - -template class tlm_array; - -//--------------------------------------------------------------------------- -// Classes for the extension mechanism -//--------------------------------------------------------------------------- - -namespace -{ - -class tlm_extension_registry -{ - typedef unsigned int key_type; - typedef std::map 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(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(&m_data[i]) &= - ~*reinterpret_cast(m_byte_enable); - *reinterpret_cast(&m_data[i]) |= - *reinterpret_cast(&other.m_data[i]) & - *reinterpret_cast(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(&m_data[i]) &= - ~*reinterpret_cast(m_byte_enable); - *reinterpret_cast(&m_data[i]) |= - *reinterpret_cast(&other.m_data[i]) & - *reinterpret_cast(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(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(nullptr); - } -} - -void -tlm_generic_payload::resize_extensions() -{ - m_extensions.expand(max_num_extensions()); -} - -} // namespace tlm diff --git a/src/systemc/tlm_core/tlm_2/tlm_generic_payload/tlm_phase.cc b/src/systemc/tlm_core/tlm_2/tlm_generic_payload/tlm_phase.cc new file mode 100644 index 000000000..2c8b1e1a0 --- /dev/null +++ b/src/systemc/tlm_core/tlm_2/tlm_generic_payload/tlm_phase.cc @@ -0,0 +1,111 @@ +/***************************************************************************** + + 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 +#include +#include +#include + +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(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 type_map; + typedef std::vector 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 diff --git a/src/systemc/tlm_core/tlm_2/tlm_generic_payload/tlm_phase.cpp b/src/systemc/tlm_core/tlm_2/tlm_generic_payload/tlm_phase.cpp deleted file mode 100644 index 2c8b1e1a0..000000000 --- a/src/systemc/tlm_core/tlm_2/tlm_generic_payload/tlm_phase.cpp +++ /dev/null @@ -1,111 +0,0 @@ -/***************************************************************************** - - 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 -#include -#include -#include - -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(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 type_map; - typedef std::vector 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 diff --git a/src/systemc/tlm_core/tlm_2/tlm_quantum/SConscript b/src/systemc/tlm_core/tlm_2/tlm_quantum/SConscript new file mode 100644 index 000000000..bdfc2a034 --- /dev/null +++ b/src/systemc/tlm_core/tlm_2/tlm_quantum/SConscript @@ -0,0 +1,31 @@ +# 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') diff --git a/src/systemc/tlm_core/tlm_2/tlm_quantum/tlm_global_quantum.cc b/src/systemc/tlm_core/tlm_2/tlm_quantum/tlm_global_quantum.cc new file mode 100644 index 000000000..7ba44e3cb --- /dev/null +++ b/src/systemc/tlm_core/tlm_2/tlm_quantum/tlm_global_quantum.cc @@ -0,0 +1,49 @@ +/***************************************************************************** + + 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 +#include + +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 diff --git a/src/systemc/tlm_core/tlm_2/tlm_quantum/tlm_global_quantum.cpp b/src/systemc/tlm_core/tlm_2/tlm_quantum/tlm_global_quantum.cpp deleted file mode 100644 index 7ba44e3cb..000000000 --- a/src/systemc/tlm_core/tlm_2/tlm_quantum/tlm_global_quantum.cpp +++ /dev/null @@ -1,49 +0,0 @@ -/***************************************************************************** - - 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 -#include - -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 diff --git a/src/systemc/tlm_utils/SConscript b/src/systemc/tlm_utils/SConscript new file mode 100644 index 000000000..354bd1f54 --- /dev/null +++ b/src/systemc/tlm_utils/SConscript @@ -0,0 +1,32 @@ +# 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') diff --git a/src/systemc/tlm_utils/convenience_socket_bases.cc b/src/systemc/tlm_utils/convenience_socket_bases.cc new file mode 100644 index 000000000..ba38d6c79 --- /dev/null +++ b/src/systemc/tlm_utils/convenience_socket_bases.cc @@ -0,0 +1,86 @@ +/***************************************************************************** + + 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 + +#include +#include + +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 diff --git a/src/systemc/tlm_utils/convenience_socket_bases.cpp b/src/systemc/tlm_utils/convenience_socket_bases.cpp deleted file mode 100644 index ba38d6c79..000000000 --- a/src/systemc/tlm_utils/convenience_socket_bases.cpp +++ /dev/null @@ -1,86 +0,0 @@ -/***************************************************************************** - - 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 - -#include -#include - -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 diff --git a/src/systemc/tlm_utils/instance_specific_extensions.cc b/src/systemc/tlm_utils/instance_specific_extensions.cc new file mode 100644 index 000000000..c0836cd67 --- /dev/null +++ b/src/systemc/tlm_utils/instance_specific_extensions.cc @@ -0,0 +1,266 @@ +/***************************************************************************** + + 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 + +#include +#include +#include +#include + +namespace tlm +{ + +template class tlm_array; + +} // namespace tlm + +namespace tlm_utils +{ + +namespace +{ + +class ispex_registry // Copied from tlm_gp.cpp. +{ + typedef unsigned int key_type; + typedef std::map 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(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(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 diff --git a/src/systemc/tlm_utils/instance_specific_extensions.cpp b/src/systemc/tlm_utils/instance_specific_extensions.cpp deleted file mode 100644 index c0836cd67..000000000 --- a/src/systemc/tlm_utils/instance_specific_extensions.cpp +++ /dev/null @@ -1,266 +0,0 @@ -/***************************************************************************** - - 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 - -#include -#include -#include -#include - -namespace tlm -{ - -template class tlm_array; - -} // namespace tlm - -namespace tlm_utils -{ - -namespace -{ - -class ispex_registry // Copied from tlm_gp.cpp. -{ - typedef unsigned int key_type; - typedef std::map 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(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(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 -- cgit v1.2.3