From fc44c22d2d4f0efb630c0eb06b0e164bd74503dc Mon Sep 17 00:00:00 2001 From: Jui-min Lee Date: Wed, 18 Nov 2020 23:30:27 +0800 Subject: [PATCH] systemc: Make tlm/gem5 packet conversion flexible We used to have a hard-coded packet2payload and payload2packet in the tlm_bridge implementation. However, as the conversion is operated on generic tlm payload, we're not able to handle information stored in any user defined SystemC extensions. In this CL, we add a pair of function to register extra conversion steps between tlm payload and gem5 packet. This decouples the exact conversion logic and enables SystemC users to register any necessary steps for their extensions. Change-Id: I70b3405395fed0f757f0fb7e19136f47d84ac115 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/37075 Reviewed-by: Gabe Black Maintainer: Gabe Black Tested-by: kokoro --- src/systemc/tlm_bridge/gem5_to_tlm.cc | 28 +++++++++++++++++++++++++++ src/systemc/tlm_bridge/gem5_to_tlm.hh | 6 ++++++ src/systemc/tlm_bridge/tlm_to_gem5.cc | 28 +++++++++++++++++++++++++++ src/systemc/tlm_bridge/tlm_to_gem5.hh | 11 +++++++++-- 4 files changed, 71 insertions(+), 2 deletions(-) diff --git a/src/systemc/tlm_bridge/gem5_to_tlm.cc b/src/systemc/tlm_bridge/gem5_to_tlm.cc index ba8f121a2..f03548ced 100644 --- a/src/systemc/tlm_bridge/gem5_to_tlm.cc +++ b/src/systemc/tlm_bridge/gem5_to_tlm.cc @@ -58,6 +58,8 @@ #include "systemc/tlm_bridge/gem5_to_tlm.hh" +#include + #include "params/Gem5ToTlmBridge32.hh" #include "params/Gem5ToTlmBridge64.hh" #include "sim/system.hh" @@ -73,6 +75,27 @@ namespace sc_gem5 */ Gem5SystemC::MemoryManager mm; +namespace +{ +/** + * Hold all the callbacks necessary to convert a gem5 packet to tlm payload. + */ +std::vector extraPacketToPayloadSteps; +} // namespace + +/** + * Notify the Gem5ToTlm bridge that we need an extra step to properly convert a + * gem5 packet to tlm payload. This can be useful when there exists a SystemC + * extension that requires information in gem5 packet. For example, if a user + * defined a SystemC extension the carries stream_id, the user may add a step + * here to read stream_id out and set the extension properly. + */ +void +addPacketToPayloadConversionStep(PacketToPayloadConversionStep step) +{ + extraPacketToPayloadSteps.push_back(std::move(step)); +} + /** * Convert a gem5 packet to a TLM payload by copying all the relevant * information to new tlm payload. @@ -110,6 +133,11 @@ packet2payload(PacketPtr packet) auto *extension = new Gem5SystemC::Gem5Extension(packet); trans->set_auto_extension(extension); + // Apply all conversion steps necessary in this specific setup. + for (auto &step : extraPacketToPayloadSteps) { + step(packet, *trans); + } + return trans; } diff --git a/src/systemc/tlm_bridge/gem5_to_tlm.hh b/src/systemc/tlm_bridge/gem5_to_tlm.hh index 25720278e..d29bfd7c6 100644 --- a/src/systemc/tlm_bridge/gem5_to_tlm.hh +++ b/src/systemc/tlm_bridge/gem5_to_tlm.hh @@ -59,6 +59,7 @@ #ifndef __SYSTEMC_TLM_BRIDGE_GEM5_TO_TLM_HH__ #define __SYSTEMC_TLM_BRIDGE_GEM5_TO_TLM_HH__ +#include #include #include "mem/port.hh" @@ -73,6 +74,11 @@ namespace sc_gem5 { +using PacketToPayloadConversionStep = + std::function; + +void addPacketToPayloadConversionStep(PacketToPayloadConversionStep step); + tlm::tlm_generic_payload *packet2payload(PacketPtr packet); class Gem5ToTlmBridgeBase : public sc_core::sc_module diff --git a/src/systemc/tlm_bridge/tlm_to_gem5.cc b/src/systemc/tlm_bridge/tlm_to_gem5.cc index 0cc0d7ff4..a1a8382cd 100644 --- a/src/systemc/tlm_bridge/tlm_to_gem5.cc +++ b/src/systemc/tlm_bridge/tlm_to_gem5.cc @@ -57,6 +57,8 @@ #include "systemc/tlm_bridge/tlm_to_gem5.hh" +#include + #include "params/TlmToGem5Bridge32.hh" #include "params/TlmToGem5Bridge64.hh" #include "sim/system.hh" @@ -66,6 +68,27 @@ namespace sc_gem5 { +namespace +{ +/** + * Hold all the callbacks necessary to convert a tlm payload to gem5 packet. + */ +std::vector extraPayloadToPacketSteps; +} // namespace + +/** + * Notify the Tlm2Gem5 bridge that we need an extra step to properly convert a + * tlm payload to gem5 packet. This can be useful when there exists a SystemC + * extension that carries extra information. For example, SystemC user might + * define an extension to store stream_id, the user may then add an extra step + * to set the generated request's stream_id accordingly. + */ +void +addPayloadToPacketConversionStep(PayloadToPacketConversionStep step) +{ + extraPayloadToPacketSteps.push_back(std::move(step)); +} + PacketPtr payload2packet(RequestorID _id, tlm::tlm_generic_payload &trans) { @@ -96,6 +119,11 @@ payload2packet(RequestorID _id, tlm::tlm_generic_payload &trans) auto pkt = new Packet(req, cmd); pkt->dataStatic(trans.get_data_ptr()); + // Apply all conversion steps necessary in this specific setup. + for (auto &step : extraPayloadToPacketSteps) { + step(pkt, trans); + } + return pkt; } diff --git a/src/systemc/tlm_bridge/tlm_to_gem5.hh b/src/systemc/tlm_bridge/tlm_to_gem5.hh index 279f76d64..13a6f24ff 100644 --- a/src/systemc/tlm_bridge/tlm_to_gem5.hh +++ b/src/systemc/tlm_bridge/tlm_to_gem5.hh @@ -58,6 +58,8 @@ #ifndef __SYSTEMC_TLM_BRIDGE_TLM_TO_GEM5_HH__ #define __SYSTEMC_TLM_BRIDGE_TLM_TO_GEM5_HH__ +#include + #include "mem/port.hh" #include "params/TlmToGem5BridgeBase.hh" #include "systemc/ext/core/sc_module.hh" @@ -71,14 +73,19 @@ namespace sc_gem5 { +using PayloadToPacketConversionStep = + std::function; + +void addPayloadToPacketConversionStep(PayloadToPacketConversionStep step); + +PacketPtr payload2packet(RequestorID _id, tlm::tlm_generic_payload &trans); + class TlmToGem5BridgeBase : public sc_core::sc_module { protected: using sc_core::sc_module::sc_module; }; -PacketPtr payload2packet(tlm::tlm_generic_payload &trans); - template class TlmToGem5Bridge : public TlmToGem5BridgeBase { -- 2.30.2