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 <giacomo.travaglini@arm.com>
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/50367
Reviewed-by: Jason Lowe-Power <power.jg@gmail.com>
Maintainer: Jason Lowe-Power <power.jg@gmail.com>
Tested-by: kokoro <noreply+kokoro@google.com>
diff --git a/src/mem/ruby/slicc_interface/AbstractController.cc b/src/mem/ruby/slicc_interface/AbstractController.cc
index c7f22a6..396b128 100644
--- a/src/mem/ruby/slicc_interface/AbstractController.cc
+++ b/src/mem/ruby/slicc_interface/AbstractController.cc
@@ -61,6 +61,7 @@
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 @@
{
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 @@
scheduleEvent(Cycles(1));
} else {
scheduleEvent(Cycles(1));
+ m_waiting_mem_retry = true;
delete pkt;
delete s;
}
@@ -441,6 +443,7 @@
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 3fe2205..56c164f 100644
--- a/src/mem/ruby/slicc_interface/AbstractController.hh
+++ b/src/mem/ruby/slicc_interface/AbstractController.hh
@@ -328,6 +328,7 @@
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