From 7260394d4bdf4bca51934fafc76f4222e67f99e9 Mon Sep 17 00:00:00 2001 From: Giacomo Travaglini Date: Mon, 13 Sep 2021 10:23:19 +0100 Subject: [PATCH] mem: Make ruby AbstractController compatible with XBar At the moment the ruby AbstractController is trying to re-send the same memory request every clock cycle until it finally succeeds [1] (in other words it is not waiting for a recvReqRetry from the peer port) This polling behaviour is not compatible with the gem5 XBar, which is panicking if it receives two consecutive requests to the same BUSY layer [2] This patch is fixing the incompatibility by inhibiting the AbstractController retry until it gets a notification from the peer response port [1]: https://github.com/gem5/gem5/blob/v21.1.0.1/\ src/mem/ruby/slicc_interface/AbstractController.cc#L303 [2]: https://github.com/gem5/gem5/blob/v21.1.0.1/src/mem/xbar.cc#L196 Change-Id: I0ac38ce286051fb714844de569c2ebf85e71a523 Signed-off-by: Giacomo Travaglini Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/50367 Reviewed-by: Jason Lowe-Power Maintainer: Jason Lowe-Power Tested-by: kokoro --- src/mem/ruby/slicc_interface/AbstractController.cc | 5 ++++- src/mem/ruby/slicc_interface/AbstractController.hh | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/mem/ruby/slicc_interface/AbstractController.cc b/src/mem/ruby/slicc_interface/AbstractController.cc index c7f22a60a3..396b128e42 100644 --- a/src/mem/ruby/slicc_interface/AbstractController.cc +++ b/src/mem/ruby/slicc_interface/AbstractController.cc @@ -61,6 +61,7 @@ AbstractController::AbstractController(const Params &p) m_transitions_per_cycle(p.transitions_per_cycle), m_buffer_size(p.buffer_size), m_recycle_latency(p.recycle_latency), m_mandatory_queue_latency(p.mandatory_queue_latency), + m_waiting_mem_retry(false), memoryPort(csprintf("%s.memory", name()), this), addrRanges(p.addr_ranges.begin(), p.addr_ranges.end()), stats(this) @@ -255,7 +256,7 @@ AbstractController::serviceMemoryQueue() { auto mem_queue = getMemReqQueue(); assert(mem_queue); - if (!mem_queue->isReady(clockEdge())) { + if (m_waiting_mem_retry || !mem_queue->isReady(clockEdge())) { return false; } @@ -301,6 +302,7 @@ AbstractController::serviceMemoryQueue() scheduleEvent(Cycles(1)); } else { scheduleEvent(Cycles(1)); + m_waiting_mem_retry = true; delete pkt; delete s; } @@ -441,6 +443,7 @@ AbstractController::MemoryPort::recvTimingResp(PacketPtr pkt) void AbstractController::MemoryPort::recvReqRetry() { + controller->m_waiting_mem_retry = false; controller->serviceMemoryQueue(); } diff --git a/src/mem/ruby/slicc_interface/AbstractController.hh b/src/mem/ruby/slicc_interface/AbstractController.hh index 3fe220582a..56c164f06f 100644 --- a/src/mem/ruby/slicc_interface/AbstractController.hh +++ b/src/mem/ruby/slicc_interface/AbstractController.hh @@ -328,6 +328,7 @@ class AbstractController : public ClockedObject, public Consumer const unsigned int m_buffer_size; Cycles m_recycle_latency; const Cycles m_mandatory_queue_latency; + bool m_waiting_mem_retry; /** * Port that forwards requests and receives responses from the