systemc: Fix tlm phase ordering in Gem5ToTlmBridge

Previously we only rely on timestamp to schedule all phase change events
of tlm transactions in Gem5ToTlmBridge. However, it is valid to have
END_REQ and BEGIN_RESP of a transaction to be scheduled at the same
timestamp and the gem5 scheduler will not necessary order them in a
correct way.

This unfortunately breaks the code as sending a response before
accepting a request doesn't make sense at all and will trigger an
assertion failure.

In this CL we slightly increase the priority of END_REQ event so we can
always process phase change events in a correct order.

Change-Id: Ic33a92162c8c53af3887c7b04090115a38f96866
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/44305
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:
Jui-min Lee
2021-04-12 16:40:48 +08:00
parent d1e090eec4
commit c4aad44a62

View File

@@ -62,6 +62,7 @@
#include "params/Gem5ToTlmBridge32.hh"
#include "params/Gem5ToTlmBridge64.hh"
#include "sim/eventq.hh"
#include "sim/system.hh"
#include "systemc/tlm_bridge/sc_ext.hh"
#include "systemc/tlm_bridge/sc_mm.hh"
@@ -69,6 +70,24 @@
namespace sc_gem5
{
/**
* Helper function to help set priority of phase change events of tlm
* transactions. This is to workaround the uncertainty of gem5 eventq if
* multiple events are scheduled at the same timestamp.
*/
static EventBase::Priority
getPriorityOfTlmPhase(const tlm::tlm_phase& phase)
{
// In theory, for all phase change events of a specific TLM base protocol
// transaction, only tlm::END_REQ and tlm::BEGIN_RESP would be scheduled at
// the same time in the same queue. So we only need to ensure END_REQ has a
// higher priority (less in pri value) than BEGIN_RESP.
if (phase == tlm::END_REQ) {
return EventBase::Default_Pri - 1;
}
return EventBase::Default_Pri;
}
/**
* Instantiate a tlm memory manager that takes care about all the
* tlm transactions in the system.
@@ -367,8 +386,9 @@ Gem5ToTlmBridge<BITWIDTH>::recvTimingReq(PacketPtr packet)
// Accepted but is now blocking until END_REQ (exclusion rule).
blockingRequest = trans;
auto cb = [this, trans, phase]() { pec(*trans, phase); };
system->schedule(new EventFunctionWrapper(cb, "pec", true),
curTick() + delay.value());
auto event = new EventFunctionWrapper(
cb, "pec", true, getPriorityOfTlmPhase(phase));
system->schedule(event, curTick() + delay.value());
} else if (status == tlm::TLM_COMPLETED) {
// Transaction is over nothing has do be done.
sc_assert(phase == tlm::END_RESP);
@@ -442,8 +462,9 @@ Gem5ToTlmBridge<BITWIDTH>::nb_transport_bw(tlm::tlm_generic_payload &trans,
tlm::tlm_phase &phase, sc_core::sc_time &delay)
{
auto cb = [this, &trans, phase]() { pec(trans, phase); };
system->schedule(new EventFunctionWrapper(cb, "pec", true),
curTick() + delay.value());
auto event = new EventFunctionWrapper(
cb, "pec", true, getPriorityOfTlmPhase(phase));
system->schedule(event, curTick() + delay.value());
return tlm::TLM_ACCEPTED;
}