diff --git a/src/common/util/range_lut.h b/src/common/util/range_lut.h index 3e549db79..a6b683bce 100644 --- a/src/common/util/range_lut.h +++ b/src/common/util/range_lut.h @@ -205,7 +205,7 @@ template inline std::string range_lut::toString() const { break; case END_RANGE: buf << " to 0x" << std::setw(sizeof(uint64_t) * 2) << std::setfill('0') << std::uppercase << std::hex << iter->first << std::dec - << " as " << iter->second->index << std::endl; + << " as " << iter->second.index << std::endl; } } return buf.str(); diff --git a/src/components/scc/memory.h b/src/components/scc/memory.h index d15ea9ecd..ed14c4e56 100644 --- a/src/components/scc/memory.h +++ b/src/components/scc/memory.h @@ -18,6 +18,7 @@ #define _SYSC_MEMORY_H_ // Needed for the simple_target_socket +#include #include #ifndef SC_INCLUDE_DYNAMIC_PROCESSES #define SC_INCLUDE_DYNAMIC_PROCESSES @@ -201,6 +202,11 @@ memory::memory(const sc_core::sc_mod operation_cb ? operation_cb(*this, gp, delay) : handle_operation(gp, delay); }); target.register_transport_dbg([this](tlm::tlm_generic_payload& gp) -> unsigned { + if(gp.get_command() == tlm::TLM_IGNORE_COMMAND) + if(auto ext = gp.get_extension()) { + ext->node.name = name(); + return 0; + } sc_core::sc_time z = sc_core::SC_ZERO_TIME; if(auto ext = gp.get_extension()) { if(ext->ptr) diff --git a/src/components/scc/register.h b/src/components/scc/register.h index 4fba8b536..f6b8ae897 100644 --- a/src/components/scc/register.h +++ b/src/components/scc/register.h @@ -27,6 +27,7 @@ #include #include #include +#include #ifdef _MSC_VER #include #else @@ -115,6 +116,12 @@ template class sc_register : public sc_core::sc_object, publ * @return true if this component shall be traced */ bool is_trace_enabled() const override { return enable_tracing.get_value(); } + /** + * @brief return the name of the resource + * + * @return the name + */ + char const* full_name() const override { return name(); }; /** * @fn size_t size()const * @brief get the size of this register in bytes @@ -483,6 +490,7 @@ template struct sc_register_mem : public indexe private: struct mem_wrapper : public resource_access_if { ~mem_wrapper() = default; + char const* full_name() const override { return "memory"; }; std::size_t size() const override { return sizeof(DATATYPE); }; void reset() override { elem = 0; }; bool write(const uint8_t* data, std::size_t length, uint64_t offset, sc_core::sc_time& d) override { diff --git a/src/components/scc/resource_access_if.h b/src/components/scc/resource_access_if.h index 37fa1f96d..86e5ad763 100644 --- a/src/components/scc/resource_access_if.h +++ b/src/components/scc/resource_access_if.h @@ -31,7 +31,12 @@ class resource_access_if { public: virtual ~resource_access_if() = default; /** - * @fn std::size_t size()const =0 + * @brief return the name of the resource + * + * @return the name + */ + virtual char const* full_name() const = 0; + /** * @brief return the size of the resource * * @return the size diff --git a/src/components/scc/router.h b/src/components/scc/router.h index 047e445b5..7e0c9ba56 100644 --- a/src/components/scc/router.h +++ b/src/components/scc/router.h @@ -21,11 +21,12 @@ #include #include #include -#include #include +#include #include #include #include +#include #include #include @@ -322,6 +323,33 @@ bool router::get_direct_mem_ptr(int i, tlm::tlm_ge } template unsigned router::transport_dbg(int i, tlm::tlm_generic_payload& trans) { + if(trans.get_command() == tlm::TLM_IGNORE_COMMAND) { + if(auto ext = trans.get_extension()) { + ext->node.name = name(); + auto start_addr = ext->node.start; + for(auto e : addr_decoder) { + auto addr = ext->offset + e.first; + auto entry = e.second; + switch(entry.type) { + case util::range_lut::BEGIN_RANGE: + start_addr = addr; + break; + case util::range_lut::SINGLE_BYTE_RANGE: + start_addr = addr; + case util::range_lut::END_RANGE: { + ext->node.elemets.emplace_back(start_addr, ext->offset + addr); + auto new_ext = tlm::scc::memory_map_extension(ext->node.elemets.back()); + new_ext.offset = start_addr; + trans.set_extension(&new_ext); + initiator[entry.index]->transport_dbg(trans); + trans.set_extension(ext); + break; + } + } + } + return 0; + } + } ::sc_dt::uint64 address = trans.get_address(); if(ibases[i]) { address += ibases[i]; @@ -360,6 +388,7 @@ void router::invalidate_direct_mem_ptr(int id, ::s } template void router::end_of_elaboration() { addr_decoder.validate(); + SCCDEBUG(SCOBJ) << "address map\n" << addr_decoder.toString(); } } // namespace scc diff --git a/src/components/scc/tlm_target.h b/src/components/scc/tlm_target.h index 2d81bb113..3b4955d8d 100644 --- a/src/components/scc/tlm_target.h +++ b/src/components/scc/tlm_target.h @@ -18,11 +18,11 @@ #define _SYSC_TLM_TARGET_H_ #include "resource_access_if.h" -#include -#include #include +#include #include #include +#include #include namespace scc { @@ -107,7 +107,8 @@ template class tlm::tlm_generic_payload* current_payload{nullptr}; protected: - util::range_lut> socket_map; + using resource_access_t = std::pair; + util::range_lut socket_map; template T* get_payload_extension() { if(current_payload) return current_payload->get_extension(); @@ -221,6 +222,29 @@ void scc::tlm_target::b_tranport_cb(tlm::tlm_gener template unsigned int scc::tlm_target::tranport_dbg_cb(tlm::tlm_generic_payload& gp) { + if(gp.get_command() == tlm::TLM_IGNORE_COMMAND) + if(auto ext = gp.get_extension()) { + std::string name = socket.name(); + ext->node.name = name.substr(0, name.length() - strlen(socket.basename()) - 1); + auto start_addr = ext->node.start; + for(auto e : socket_map) { + auto addr = ext->offset + e.first; + auto entry = e.second; + switch(entry.type) { + case util::range_lut::BEGIN_RANGE: + start_addr = addr; + break; + case util::range_lut::SINGLE_BYTE_RANGE: + start_addr = addr; + case util::range_lut::END_RANGE: { + ext->node.elemets.emplace_back(start_addr, ext->offset + addr); + ext->node.elemets.back().name = entry.index.first->full_name(); + break; + } + } + } + return 0; + } resource_access_if* ra = nullptr; uint64_t base = 0; std::tie(ra, base) = socket_map.getEntry(gp.get_address()); diff --git a/src/components/scc/tlm_target_bfs_register_base.h b/src/components/scc/tlm_target_bfs_register_base.h index 6f0464b10..21be68e72 100644 --- a/src/components/scc/tlm_target_bfs_register_base.h +++ b/src/components/scc/tlm_target_bfs_register_base.h @@ -104,10 +104,14 @@ template class bitfield_register : public sc_core::sc_obje , writeMask{writeMask} , readMask{readMask} {} + /** + * @return the name + */ + char const* full_name() const override { return name(); }; /** * @return The size of the register in bytes */ - constexpr size_t size() const noexcept override { return sizeof(datatype_t); } + size_t size() const noexcept override { return sizeof(datatype_t); } void reset() override { storage = resetValue; } diff --git a/src/sysc/tlm/scc/memory_map_collector.h b/src/sysc/tlm/scc/memory_map_collector.h new file mode 100644 index 000000000..08f4f3bf5 --- /dev/null +++ b/src/sysc/tlm/scc/memory_map_collector.h @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright 2016, 2018 MINRES Technologies GmbH + * + * Licensed 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. + *******************************************************************************/ + +#ifndef _TLM_SCC_MEMORY_MAP_COLLECTOR_H_ +#define _TLM_SCC_MEMORY_MAP_COLLECTOR_H_ + +#include +#include +#include +#include +#include +#include +#include + +//! @brief SystemC TLM +namespace tlm { +//! @brief SCC TLM utilities +namespace scc { +struct memory_node { + uint64_t start{0}; + uint64_t end{std::numeric_limits::max()}; + std::string name; + std::vector elemets; + memory_node(uint64_t start, uint64_t end) + : start(start) + , end(end) {} + memory_node() = default; + std::string to_string(std::string const& prefix = "") const { + std::ostringstream os; + std::string filler(16 - prefix.length(), ' '); + os << fmt::format("{} 0x{:016x}:0x{:016x}{}{}\n", prefix, start, end, filler, name); + for(auto e : elemets) + os << e.to_string(prefix + " "); + return os.str(); + } +}; + +struct memory_map_extension : tlm::tlm_extension { + tlm_extension_base* clone() const override { return new memory_map_extension(*this); } + void copy_from(tlm_extension_base const& from) override { throw std::runtime_error("copying of memory_map_extension not allowed"); } + + memory_map_extension(memory_node& node) + : node(node) {} + ~memory_map_extension() {} + + memory_node& node; + uint64_t offset{0}; +}; + +template +memory_node gather_memory(sc_core::sc_port_b>& port) { + memory_node root; + auto ext = memory_map_extension(root); + /*TYPES::tlm_payload_type*/ tlm::tlm_generic_payload trans; + trans.set_extension(&ext); + port->transport_dbg(trans); + trans.set_extension(nullptr); + return std::move(root); +} +} // namespace scc +} // namespace tlm +#endif // _TLM_SCC_MEMORY_MAP_COLLECTOR_H_ \ No newline at end of file diff --git a/src/sysc/tlm/scc/tlm_id.h b/src/sysc/tlm/scc/tlm_id.h index 5deb74a6f..3273ab18b 100644 --- a/src/sysc/tlm/scc/tlm_id.h +++ b/src/sysc/tlm/scc/tlm_id.h @@ -25,11 +25,8 @@ namespace tlm { namespace scc { struct tlm_id_extension : public tlm_extension { - virtual tlm_extension_base* clone() const { - auto* t = new tlm_id_extension(this->id); - return t; - } - virtual void copy_from(tlm_extension_base const& from) { id = static_cast(from).id; } + tlm_extension_base* clone() const override { return new tlm_id_extension(this->id); } + void copy_from(tlm_extension_base const& from) override { id = static_cast(from).id; } tlm_id_extension(tlm_gp_shared_ptr& i) : tlm_id_extension(reinterpret_cast(i.get())) {} tlm_id_extension(void* i) @@ -65,13 +62,17 @@ inline void setId(tlm::tlm_generic_payload& gp, uintptr_t id) { } struct initiator_id_extension : public tlm_extension { - virtual tlm_extension_base* clone() const { - auto* t = new initiator_id_extension(this->id); - return t; - } - virtual void copy_from(tlm_extension_base const& from) {} + tlm_extension_base* clone() const override { return new initiator_id_extension(*this); } + void copy_from(tlm_extension_base const& from) override {} + initiator_id_extension(uint64_t i) : id(i) {} + + initiator_id_extension(initiator_id_extension const& o) + : id(o.id) {} + + virtual ~initiator_id_extension() = default; + const uint64_t id; };