systemc: Make tlm/gem5 packet conversion flexible
authorJui-min Lee <fcrh@google.com>
Wed, 18 Nov 2020 15:30:27 +0000 (23:30 +0800)
committerJui-min Lee <fcrh@google.com>
Thu, 19 Nov 2020 07:50:20 +0000 (07:50 +0000)
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 <gabe.black@gmail.com>
Maintainer: Gabe Black <gabe.black@gmail.com>
Tested-by: kokoro <noreply+kokoro@google.com>
src/systemc/tlm_bridge/gem5_to_tlm.cc
src/systemc/tlm_bridge/gem5_to_tlm.hh
src/systemc/tlm_bridge/tlm_to_gem5.cc
src/systemc/tlm_bridge/tlm_to_gem5.hh

index ba8f121a2e8fa20fef18b730481e2fecaccda30c..f03548ced9f0553cb10b92c17f06048917dd0d97 100644 (file)
@@ -58,6 +58,8 @@
 
 #include "systemc/tlm_bridge/gem5_to_tlm.hh"
 
+#include <utility>
+
 #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<PacketToPayloadConversionStep> 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;
 }
 
index 25720278e48f549d4982eb9b8da7649ebf38539f..d29bfd7c698a3808ed73d2f9ee5c566219912931 100644 (file)
@@ -59,6 +59,7 @@
 #ifndef __SYSTEMC_TLM_BRIDGE_GEM5_TO_TLM_HH__
 #define __SYSTEMC_TLM_BRIDGE_GEM5_TO_TLM_HH__
 
+#include <functional>
 #include <string>
 
 #include "mem/port.hh"
 namespace sc_gem5
 {
 
+using PacketToPayloadConversionStep =
+    std::function<void(PacketPtr pkt, tlm::tlm_generic_payload &trans)>;
+
+void addPacketToPayloadConversionStep(PacketToPayloadConversionStep step);
+
 tlm::tlm_generic_payload *packet2payload(PacketPtr packet);
 
 class Gem5ToTlmBridgeBase : public sc_core::sc_module
index 0cc0d7ff4b66206a4bc05a1468ca2f8b0b8add74..a1a8382cd48818fbb3a4b9058e9681e77c183966 100644 (file)
@@ -57,6 +57,8 @@
 
 #include "systemc/tlm_bridge/tlm_to_gem5.hh"
 
+#include <utility>
+
 #include "params/TlmToGem5Bridge32.hh"
 #include "params/TlmToGem5Bridge64.hh"
 #include "sim/system.hh"
 namespace sc_gem5
 {
 
+namespace
+{
+/**
+ * Hold all the callbacks necessary to convert a tlm payload to gem5 packet.
+ */
+std::vector<PayloadToPacketConversionStep> 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;
 }
 
index 279f76d643dfafb22c5bdb7291e1d34562b234cc..13a6f24ff6cc2c9fa741ccf7970832c9a07cc06f 100644 (file)
@@ -58,6 +58,8 @@
 #ifndef __SYSTEMC_TLM_BRIDGE_TLM_TO_GEM5_HH__
 #define __SYSTEMC_TLM_BRIDGE_TLM_TO_GEM5_HH__
 
+#include <functional>
+
 #include "mem/port.hh"
 #include "params/TlmToGem5BridgeBase.hh"
 #include "systemc/ext/core/sc_module.hh"
 namespace sc_gem5
 {
 
+using PayloadToPacketConversionStep =
+    std::function<void(PacketPtr pkt, tlm::tlm_generic_payload &trans)>;
+
+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 <unsigned int BITWIDTH>
 class TlmToGem5Bridge : public TlmToGem5BridgeBase
 {