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 <gabe.black@gmail.com> Maintainer: Gabe Black <gabe.black@gmail.com> Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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"
|
||||
@@ -73,6 +74,11 @@
|
||||
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
|
||||
|
||||
@@ -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"
|
||||
@@ -66,6 +68,27 @@
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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"
|
||||
@@ -71,14 +73,19 @@
|
||||
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
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user