gem5-dev@gem5.org

The gem5 Developer List

View all threads

[M] Change in gem5/gem5[develop]: systemc: gem5_to_tlm bridge should reuse existed tlm payload

YW
Yu-hsin Wang (Gerrit)
Thu, Sep 22, 2022 5:56 AM

Yu-hsin Wang has uploaded this change for review. (
https://gem5-review.googlesource.com/c/public/gem5/+/63771?usp=email )

Change subject: systemc: gem5_to_tlm bridge should reuse existed tlm payload
......................................................................

systemc: gem5_to_tlm bridge should reuse existed tlm payload

Given a data path initiated from SystemC, routed by gem5, and handled
by SystemC finally.

SystemC -> gem5 -> SystemC

The target SystemC needs to get the original transaction object.
Otherwise, it would lose the extensions in the payload. This change
moves the SenderState class to public for reachability, adds the logic
in in gem5_to_tlm bridge to reuse the correct payload, and sync the
possible address translate finally.

Change-Id: Ic6d24e98454f564f7dd6b43ad8c011e1ea7ea433

M src/systemc/tlm_bridge/gem5_to_tlm.cc
M src/systemc/tlm_bridge/sc_ext.hh
M src/systemc/tlm_bridge/tlm_to_gem5.cc
M src/systemc/tlm_bridge/tlm_to_gem5.hh
4 files changed, 99 insertions(+), 27 deletions(-)

diff --git a/src/systemc/tlm_bridge/gem5_to_tlm.cc
b/src/systemc/tlm_bridge/gem5_to_tlm.cc
index 37da822..195732c 100644
--- a/src/systemc/tlm_bridge/gem5_to_tlm.cc
+++ b/src/systemc/tlm_bridge/gem5_to_tlm.cc
@@ -264,8 +264,18 @@
panic_if(packet->cacheResponding(),
"Should not see packets where cache is responding");

  • // Prepare the transaction.
  • auto *trans = packet2payload(packet);
  • tlm::tlm_generic_payload *trans = nullptr;

  • // If there is a SenderState, we can pipe through the original
    transaction.

  • // Otherwise, we generate a new transaction based on the packet.

  • auto tlmSenderState =

  •    packet->findNextSenderState<Gem5SystemC::TlmSenderState>();
    
  • if (tlmSenderState != nullptr) {

  •  trans = &tlmSenderState->trans;
    
  •  trans->set_address(packet->getAddr());
    
  • } else {

  •  trans = packet2payload(packet);
    
  • }

    sc_core::sc_time delay = sc_core::SC_ZERO_TIME;
    

@@ -277,7 +287,8 @@
if (packet->needsResponse())
packet->makeResponse();

  • trans->release();
  • if (tlmSenderState != nullptr)
  •    trans->release();
    
    return delay.value();
    
    }
    @@ -290,10 +301,20 @@
    panic_if(packet->cacheResponding(),
    "Should not see packets where cache is responding");
  • sc_core::sc_time delay = sc_core::SC_ZERO_TIME;
  • tlm::tlm_generic_payload *trans = nullptr;
  • // Prepare the transaction.
  • auto *trans = packet2payload(packet);
  • // If there is a SenderState, we can pipe through the original
    transaction.

  • // Otherwise, we generate a new transaction based on the packet.

  • auto tlmSenderState =

  •    packet->findNextSenderState<Gem5SystemC::TlmSenderState>();
    
  • if (tlmSenderState != nullptr) {

  •  trans = &tlmSenderState->trans;
    
  •  trans->set_address(packet->getAddr());
    
  • } else {

  •  trans = packet2payload(packet);
    
  • }

  • sc_core::sc_time delay = sc_core::SC_ZERO_TIME;

    if (trans->get_command() != tlm::TLM_IGNORE_COMMAND) {
    // Execute b_transport:
    @@ -310,7 +331,8 @@
    if (packet->needsResponse())
    packet->makeResponse();

  • trans->release();
  • if (tlmSenderState != nullptr)
  •    trans->release();
    
    return delay.value();
    
    }
    @@ -354,8 +376,18 @@
    * requestInProgress = trans;
    */
  • // Prepare the transaction.
  • auto *trans = packet2payload(packet);
  • tlm::tlm_generic_payload *trans = nullptr;

  • // If there is a SenderState, we can pipe through the original
    transaction.

  • // Otherwise, we generate a new transaction based on the packet.

  • auto tlmSenderState =

  •    packet->findNextSenderState<Gem5SystemC::TlmSenderState>();
    
  • if (tlmSenderState != nullptr) {

  •  trans = &tlmSenderState->trans;
    
  •  trans->set_address(packet->getAddr());
    
  • } else {

  •  trans = packet2payload(packet);
    
  • }

    /*
     * Pay for annotated transport delays.
    

@@ -405,7 +437,8 @@
} else if (status == tlm::TLM_COMPLETED) {
// Transaction is over nothing has do be done.
sc_assert(phase == tlm::END_RESP);

  •    trans->release();
    
  •    if (tlmSenderState != nullptr)
    
  •        trans->release();
    }
    
    return true;
    

@@ -456,8 +489,18 @@
void
Gem5ToTlmBridge<BITWIDTH>::recvFunctional(PacketPtr packet)
{

  • // Prepare the transaction.
  • auto *trans = packet2payload(packet);
  • tlm::tlm_generic_payload *trans = nullptr;

  • // If there is a SenderState, we can pipe through the original
    transaction.

  • // Otherwise, we generate a new transaction based on the packet.

  • auto tlmSenderState =

  •    packet->findNextSenderState<Gem5SystemC::TlmSenderState>();
    
  • if (tlmSenderState != nullptr) {

  •  trans = &tlmSenderState->trans;
    
  •  trans->set_address(packet->getAddr());
    
  • } else {

  •  trans = packet2payload(packet);
    
  • }

    /* Execute Debug Transport: */
    unsigned int bytes = socket->transport_dbg(*trans);
    

@@ -466,7 +509,8 @@
"debug transport was not completed");
}

  • trans->release();
  • if (tlmSenderState != nullptr)

  •    trans->release();
    

    }

    template <unsigned int BITWIDTH>
    diff --git a/src/systemc/tlm_bridge/sc_ext.hh
    b/src/systemc/tlm_bridge/sc_ext.hh
    index 3f7c320..bb67676 100644
    --- a/src/systemc/tlm_bridge/sc_ext.hh
    +++ b/src/systemc/tlm_bridge/sc_ext.hh
    @@ -44,6 +44,12 @@
    namespace Gem5SystemC
    {

+struct TlmSenderState : public gem5::Packet::SenderState
+{

  • tlm::tlm_generic_payload &trans;
  • TlmSenderState(tlm::tlm_generic_payload &trans) : trans(trans) {}
    +};
  • class Gem5Extension: public tlm::tlm_extension<Gem5Extension>
    {
    public:
    diff --git a/src/systemc/tlm_bridge/tlm_to_gem5.cc
    b/src/systemc/tlm_bridge/tlm_to_gem5.cc
    index 9f7c6eb..0c622f6 100644
    --- a/src/systemc/tlm_bridge/tlm_to_gem5.cc
    +++ b/src/systemc/tlm_bridge/tlm_to_gem5.cc
    @@ -208,11 +208,12 @@
    // generate a new packet based on the transaction.
    if (extension != nullptr) {
    pkt = extension->getPacket();
  •    pkt->setAddr(trans.get_address());
    } else {
        pkt = payload2packet(_id, trans);
    }
    
  • auto tlmSenderState = new TlmSenderState(trans);
  • auto tlmSenderState = new Gem5SystemC::TlmSenderState(trans);
    pkt->pushSenderState(tlmSenderState);

    // If the packet doesn't need a response, we should send BEGIN_RESP by
    @@ -332,6 +333,7 @@
    // world and we can pipe through the original packet.
    if (extension != nullptr) {
    pkt = extension->getPacket();

  •    pkt->setAddr(trans.get_address());
    } else {
        pkt = payload2packet(_id, trans);
    }
    

@@ -365,18 +367,22 @@
Gem5SystemC::Gem5Extension *extension = nullptr;
trans.get_extension(extension);

  • PacketPtr pkt = nullptr;
  • // If there is an extension, this transaction was initiated by the gem5
    // world and we can pipe through the original packet.
    if (extension != nullptr) {
    
  •    bmp.sendFunctional(extension->getPacket());
    
  •    pkt = extension->getPacket();
    
  •    pkt->setAddr(trans.get_address());
    } else {
    
  •    auto pkt = payload2packet(_id, trans);
    
  •    if (pkt) {
    
  •        bmp.sendFunctional(pkt);
    
  •        destroyPacket(pkt);
    
  •    }
    
  •    pkt = payload2packet(_id, trans);
    }
    
  • bmp.sendFunctional(pkt);

  • if (extension == nullptr)

  •    destroyPacket(pkt);
    
  • return trans.get_data_length();
    

    }

@@ -394,6 +400,7 @@
// world and we can pipe through the original packet.
if (extension != nullptr) {
pkt = extension->getPacket();

  •    pkt->setAddr(trans.get_address());
    } else {
        pkt = payload2packet(_id, trans);
        pkt->req->setFlags(Request::NO_ACCESS);
    

@@ -455,7 +462,8 @@
pkt->payloadDelay = 0;
pkt->headerDelay = 0;

  • auto tlmSenderState =
    dynamic_cast<TlmSenderState*>(pkt->popSenderState());
  • auto tlmSenderState =
  •    dynamic_cast<Gem5SystemC::TlmSenderState*>(pkt->popSenderState());
    sc_assert(tlmSenderState != nullptr);
    
    auto &trans = tlmSenderState->trans;
    

diff --git a/src/systemc/tlm_bridge/tlm_to_gem5.hh
b/src/systemc/tlm_bridge/tlm_to_gem5.hh
index b0fe62a..db430ef 100644
--- a/src/systemc/tlm_bridge/tlm_to_gem5.hh
+++ b/src/systemc/tlm_bridge/tlm_to_gem5.hh
@@ -91,12 +91,6 @@
class TlmToGem5Bridge : public TlmToGem5BridgeBase
{
private:

  • struct TlmSenderState : public gem5::Packet::SenderState
  • {
  •    tlm::tlm_generic_payload &trans;
    
  •    TlmSenderState(tlm::tlm_generic_payload &trans) : trans(trans) {}
    
  • };
  • class BridgeRequestPort : public gem5::RequestPort
    {
      protected:
    

--
To view, visit
https://gem5-review.googlesource.com/c/public/gem5/+/63771?usp=email
To unsubscribe, or for help writing mail filters, visit
https://gem5-review.googlesource.com/settings

Gerrit-Project: public/gem5
Gerrit-Branch: develop
Gerrit-Change-Id: Ic6d24e98454f564f7dd6b43ad8c011e1ea7ea433
Gerrit-Change-Number: 63771
Gerrit-PatchSet: 1
Gerrit-Owner: Yu-hsin Wang yuhsingw@google.com
Gerrit-MessageType: newchange

Yu-hsin Wang has uploaded this change for review. ( https://gem5-review.googlesource.com/c/public/gem5/+/63771?usp=email ) Change subject: systemc: gem5_to_tlm bridge should reuse existed tlm payload ...................................................................... systemc: gem5_to_tlm bridge should reuse existed tlm payload Given a data path initiated from SystemC, routed by gem5, and handled by SystemC finally. SystemC -> gem5 -> SystemC The target SystemC needs to get the original transaction object. Otherwise, it would lose the extensions in the payload. This change moves the SenderState class to public for reachability, adds the logic in in gem5_to_tlm bridge to reuse the correct payload, and sync the possible address translate finally. Change-Id: Ic6d24e98454f564f7dd6b43ad8c011e1ea7ea433 --- M src/systemc/tlm_bridge/gem5_to_tlm.cc M src/systemc/tlm_bridge/sc_ext.hh M src/systemc/tlm_bridge/tlm_to_gem5.cc M src/systemc/tlm_bridge/tlm_to_gem5.hh 4 files changed, 99 insertions(+), 27 deletions(-) diff --git a/src/systemc/tlm_bridge/gem5_to_tlm.cc b/src/systemc/tlm_bridge/gem5_to_tlm.cc index 37da822..195732c 100644 --- a/src/systemc/tlm_bridge/gem5_to_tlm.cc +++ b/src/systemc/tlm_bridge/gem5_to_tlm.cc @@ -264,8 +264,18 @@ panic_if(packet->cacheResponding(), "Should not see packets where cache is responding"); - // Prepare the transaction. - auto *trans = packet2payload(packet); + tlm::tlm_generic_payload *trans = nullptr; + + // If there is a SenderState, we can pipe through the original transaction. + // Otherwise, we generate a new transaction based on the packet. + auto tlmSenderState = + packet->findNextSenderState<Gem5SystemC::TlmSenderState>(); + if (tlmSenderState != nullptr) { + trans = &tlmSenderState->trans; + trans->set_address(packet->getAddr()); + } else { + trans = packet2payload(packet); + } sc_core::sc_time delay = sc_core::SC_ZERO_TIME; @@ -277,7 +287,8 @@ if (packet->needsResponse()) packet->makeResponse(); - trans->release(); + if (tlmSenderState != nullptr) + trans->release(); return delay.value(); } @@ -290,10 +301,20 @@ panic_if(packet->cacheResponding(), "Should not see packets where cache is responding"); - sc_core::sc_time delay = sc_core::SC_ZERO_TIME; + tlm::tlm_generic_payload *trans = nullptr; - // Prepare the transaction. - auto *trans = packet2payload(packet); + // If there is a SenderState, we can pipe through the original transaction. + // Otherwise, we generate a new transaction based on the packet. + auto tlmSenderState = + packet->findNextSenderState<Gem5SystemC::TlmSenderState>(); + if (tlmSenderState != nullptr) { + trans = &tlmSenderState->trans; + trans->set_address(packet->getAddr()); + } else { + trans = packet2payload(packet); + } + + sc_core::sc_time delay = sc_core::SC_ZERO_TIME; if (trans->get_command() != tlm::TLM_IGNORE_COMMAND) { // Execute b_transport: @@ -310,7 +331,8 @@ if (packet->needsResponse()) packet->makeResponse(); - trans->release(); + if (tlmSenderState != nullptr) + trans->release(); return delay.value(); } @@ -354,8 +376,18 @@ * requestInProgress = trans; */ - // Prepare the transaction. - auto *trans = packet2payload(packet); + tlm::tlm_generic_payload *trans = nullptr; + + // If there is a SenderState, we can pipe through the original transaction. + // Otherwise, we generate a new transaction based on the packet. + auto tlmSenderState = + packet->findNextSenderState<Gem5SystemC::TlmSenderState>(); + if (tlmSenderState != nullptr) { + trans = &tlmSenderState->trans; + trans->set_address(packet->getAddr()); + } else { + trans = packet2payload(packet); + } /* * Pay for annotated transport delays. @@ -405,7 +437,8 @@ } else if (status == tlm::TLM_COMPLETED) { // Transaction is over nothing has do be done. sc_assert(phase == tlm::END_RESP); - trans->release(); + if (tlmSenderState != nullptr) + trans->release(); } return true; @@ -456,8 +489,18 @@ void Gem5ToTlmBridge<BITWIDTH>::recvFunctional(PacketPtr packet) { - // Prepare the transaction. - auto *trans = packet2payload(packet); + tlm::tlm_generic_payload *trans = nullptr; + + // If there is a SenderState, we can pipe through the original transaction. + // Otherwise, we generate a new transaction based on the packet. + auto tlmSenderState = + packet->findNextSenderState<Gem5SystemC::TlmSenderState>(); + if (tlmSenderState != nullptr) { + trans = &tlmSenderState->trans; + trans->set_address(packet->getAddr()); + } else { + trans = packet2payload(packet); + } /* Execute Debug Transport: */ unsigned int bytes = socket->transport_dbg(*trans); @@ -466,7 +509,8 @@ "debug transport was not completed"); } - trans->release(); + if (tlmSenderState != nullptr) + trans->release(); } template <unsigned int BITWIDTH> diff --git a/src/systemc/tlm_bridge/sc_ext.hh b/src/systemc/tlm_bridge/sc_ext.hh index 3f7c320..bb67676 100644 --- a/src/systemc/tlm_bridge/sc_ext.hh +++ b/src/systemc/tlm_bridge/sc_ext.hh @@ -44,6 +44,12 @@ namespace Gem5SystemC { +struct TlmSenderState : public gem5::Packet::SenderState +{ + tlm::tlm_generic_payload &trans; + TlmSenderState(tlm::tlm_generic_payload &trans) : trans(trans) {} +}; + class Gem5Extension: public tlm::tlm_extension<Gem5Extension> { public: diff --git a/src/systemc/tlm_bridge/tlm_to_gem5.cc b/src/systemc/tlm_bridge/tlm_to_gem5.cc index 9f7c6eb..0c622f6 100644 --- a/src/systemc/tlm_bridge/tlm_to_gem5.cc +++ b/src/systemc/tlm_bridge/tlm_to_gem5.cc @@ -208,11 +208,12 @@ // generate a new packet based on the transaction. if (extension != nullptr) { pkt = extension->getPacket(); + pkt->setAddr(trans.get_address()); } else { pkt = payload2packet(_id, trans); } - auto tlmSenderState = new TlmSenderState(trans); + auto tlmSenderState = new Gem5SystemC::TlmSenderState(trans); pkt->pushSenderState(tlmSenderState); // If the packet doesn't need a response, we should send BEGIN_RESP by @@ -332,6 +333,7 @@ // world and we can pipe through the original packet. if (extension != nullptr) { pkt = extension->getPacket(); + pkt->setAddr(trans.get_address()); } else { pkt = payload2packet(_id, trans); } @@ -365,18 +367,22 @@ Gem5SystemC::Gem5Extension *extension = nullptr; trans.get_extension(extension); + PacketPtr pkt = nullptr; + // If there is an extension, this transaction was initiated by the gem5 // world and we can pipe through the original packet. if (extension != nullptr) { - bmp.sendFunctional(extension->getPacket()); + pkt = extension->getPacket(); + pkt->setAddr(trans.get_address()); } else { - auto pkt = payload2packet(_id, trans); - if (pkt) { - bmp.sendFunctional(pkt); - destroyPacket(pkt); - } + pkt = payload2packet(_id, trans); } + bmp.sendFunctional(pkt); + + if (extension == nullptr) + destroyPacket(pkt); + return trans.get_data_length(); } @@ -394,6 +400,7 @@ // world and we can pipe through the original packet. if (extension != nullptr) { pkt = extension->getPacket(); + pkt->setAddr(trans.get_address()); } else { pkt = payload2packet(_id, trans); pkt->req->setFlags(Request::NO_ACCESS); @@ -455,7 +462,8 @@ pkt->payloadDelay = 0; pkt->headerDelay = 0; - auto tlmSenderState = dynamic_cast<TlmSenderState*>(pkt->popSenderState()); + auto tlmSenderState = + dynamic_cast<Gem5SystemC::TlmSenderState*>(pkt->popSenderState()); sc_assert(tlmSenderState != nullptr); auto &trans = tlmSenderState->trans; diff --git a/src/systemc/tlm_bridge/tlm_to_gem5.hh b/src/systemc/tlm_bridge/tlm_to_gem5.hh index b0fe62a..db430ef 100644 --- a/src/systemc/tlm_bridge/tlm_to_gem5.hh +++ b/src/systemc/tlm_bridge/tlm_to_gem5.hh @@ -91,12 +91,6 @@ class TlmToGem5Bridge : public TlmToGem5BridgeBase { private: - struct TlmSenderState : public gem5::Packet::SenderState - { - tlm::tlm_generic_payload &trans; - TlmSenderState(tlm::tlm_generic_payload &trans) : trans(trans) {} - }; - class BridgeRequestPort : public gem5::RequestPort { protected: -- To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/63771?usp=email To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings Gerrit-Project: public/gem5 Gerrit-Branch: develop Gerrit-Change-Id: Ic6d24e98454f564f7dd6b43ad8c011e1ea7ea433 Gerrit-Change-Number: 63771 Gerrit-PatchSet: 1 Gerrit-Owner: Yu-hsin Wang <yuhsingw@google.com> Gerrit-MessageType: newchange