cpu: Move O3's data port into the LSQ.
That's where it's used, and putting it there avoids having to pass around the port using the top level getDataPort function. Change-Id: I0dea25d0c5f4bb3f58a6574a8f2b2d242784caf2 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/20238 Tested-by: kokoro <noreply+kokoro@google.com> Reviewed-by: Jason Lowe-Power <jason@lowepower.com> Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com> Maintainer: Gabe Black <gabeblack@google.com>
This commit is contained in:
@@ -110,32 +110,6 @@ FullO3CPU<Impl>::IcachePort::recvReqRetry()
|
||||
fetch->recvReqRetry();
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
bool
|
||||
FullO3CPU<Impl>::DcachePort::recvTimingResp(PacketPtr pkt)
|
||||
{
|
||||
return lsq->recvTimingResp(pkt);
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
void
|
||||
FullO3CPU<Impl>::DcachePort::recvTimingSnoopReq(PacketPtr pkt)
|
||||
{
|
||||
for (ThreadID tid = 0; tid < cpu->numThreads; tid++) {
|
||||
if (cpu->getCpuAddrMonitor(tid)->doMonitor(pkt)) {
|
||||
cpu->wakeup(tid);
|
||||
}
|
||||
}
|
||||
lsq->recvTimingSnoopReq(pkt);
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
void
|
||||
FullO3CPU<Impl>::DcachePort::recvReqRetry()
|
||||
{
|
||||
lsq->recvReqRetry();
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
FullO3CPU<Impl>::FullO3CPU(DerivO3CPUParams *params)
|
||||
: BaseO3CPU(params),
|
||||
@@ -175,7 +149,6 @@ FullO3CPU<Impl>::FullO3CPU(DerivO3CPUParams *params)
|
||||
isa(numThreads, NULL),
|
||||
|
||||
icachePort(&fetch, this),
|
||||
dcachePort(&iew.ldstQueue, this),
|
||||
|
||||
timeBuffer(params->backComSize, params->forwardComSize),
|
||||
fetchQueue(params->backComSize, params->forwardComSize),
|
||||
|
||||
@@ -158,49 +158,6 @@ class FullO3CPU : public BaseO3CPU
|
||||
virtual void recvReqRetry();
|
||||
};
|
||||
|
||||
/**
|
||||
* DcachePort class for the load/store queue.
|
||||
*/
|
||||
class DcachePort : public MasterPort
|
||||
{
|
||||
protected:
|
||||
|
||||
/** Pointer to LSQ. */
|
||||
LSQ<Impl> *lsq;
|
||||
FullO3CPU<Impl> *cpu;
|
||||
|
||||
public:
|
||||
/** Default constructor. */
|
||||
DcachePort(LSQ<Impl> *_lsq, FullO3CPU<Impl>* _cpu)
|
||||
: MasterPort(_cpu->name() + ".dcache_port", _cpu), lsq(_lsq),
|
||||
cpu(_cpu)
|
||||
{ }
|
||||
|
||||
protected:
|
||||
|
||||
/** Timing version of receive. Handles writing back and
|
||||
* completing the load or store that has returned from
|
||||
* memory. */
|
||||
virtual bool recvTimingResp(PacketPtr pkt);
|
||||
virtual void recvTimingSnoopReq(PacketPtr pkt);
|
||||
|
||||
virtual void recvFunctionalSnoop(PacketPtr pkt)
|
||||
{
|
||||
// @todo: Is there a need for potential invalidation here?
|
||||
}
|
||||
|
||||
/** Handles doing a retry of the previous send. */
|
||||
virtual void recvReqRetry();
|
||||
|
||||
/**
|
||||
* As this CPU requires snooping to maintain the load store queue
|
||||
* change the behaviour from the base CPU port.
|
||||
*
|
||||
* @return true since we have to snoop
|
||||
*/
|
||||
virtual bool isSnooping() const { return true; }
|
||||
};
|
||||
|
||||
/** The tick event used for scheduling CPU ticks. */
|
||||
EventFunctionWrapper tickEvent;
|
||||
|
||||
@@ -675,9 +632,6 @@ class FullO3CPU : public BaseO3CPU
|
||||
/** Instruction port. Note that it has to appear after the fetch stage. */
|
||||
IcachePort icachePort;
|
||||
|
||||
/** Data port. Note that it has to appear after the iew stages */
|
||||
DcachePort dcachePort;
|
||||
|
||||
public:
|
||||
/** Enum to give each stage a specific index, so when calling
|
||||
* activateStage() or deactivateStage(), they can specify which stage
|
||||
@@ -812,7 +766,11 @@ class FullO3CPU : public BaseO3CPU
|
||||
MasterPort &getInstPort() override { return icachePort; }
|
||||
|
||||
/** Get the dcache port (used to find block size for translations). */
|
||||
MasterPort &getDataPort() override { return dcachePort; }
|
||||
MasterPort &
|
||||
getDataPort() override
|
||||
{
|
||||
return this->iew.ldstQueue.getDataPort();
|
||||
}
|
||||
|
||||
/** Stat for total number of times the CPU is descheduled. */
|
||||
Stats::Scalar timesIdled;
|
||||
|
||||
@@ -317,7 +317,7 @@ DefaultIEW<Impl>::startupStage()
|
||||
|
||||
// Initialize the checker's dcache port here
|
||||
if (cpu->checker) {
|
||||
cpu->checker->setDcachePort(&cpu->getDataPort());
|
||||
cpu->checker->setDcachePort(&ldstQueue.getDataPort());
|
||||
}
|
||||
|
||||
cpu->activateStage(O3CPU::IEWIdx);
|
||||
|
||||
@@ -57,6 +57,9 @@
|
||||
|
||||
struct DerivO3CPUParams;
|
||||
|
||||
template <class Impl>
|
||||
class FullO3CPU;
|
||||
|
||||
template <class Impl>
|
||||
class LSQ
|
||||
|
||||
@@ -115,6 +118,49 @@ class LSQ
|
||||
void writebackDone() { _request->writebackDone(); }
|
||||
};
|
||||
|
||||
/**
|
||||
* DcachePort class for the load/store queue.
|
||||
*/
|
||||
class DcachePort : public MasterPort
|
||||
{
|
||||
protected:
|
||||
|
||||
/** Pointer to LSQ. */
|
||||
LSQ<Impl> *lsq;
|
||||
FullO3CPU<Impl> *cpu;
|
||||
|
||||
public:
|
||||
/** Default constructor. */
|
||||
DcachePort(LSQ<Impl> *_lsq, FullO3CPU<Impl>* _cpu)
|
||||
: MasterPort(_cpu->name() + ".dcache_port", _cpu), lsq(_lsq),
|
||||
cpu(_cpu)
|
||||
{ }
|
||||
|
||||
protected:
|
||||
|
||||
/** Timing version of receive. Handles writing back and
|
||||
* completing the load or store that has returned from
|
||||
* memory. */
|
||||
virtual bool recvTimingResp(PacketPtr pkt);
|
||||
virtual void recvTimingSnoopReq(PacketPtr pkt);
|
||||
|
||||
virtual void recvFunctionalSnoop(PacketPtr pkt)
|
||||
{
|
||||
// @todo: Is there a need for potential invalidation here?
|
||||
}
|
||||
|
||||
/** Handles doing a retry of the previous send. */
|
||||
virtual void recvReqRetry();
|
||||
|
||||
/**
|
||||
* As this CPU requires snooping to maintain the load store queue
|
||||
* change the behaviour from the base CPU port.
|
||||
*
|
||||
* @return true since we have to snoop
|
||||
*/
|
||||
virtual bool isSnooping() const { return true; }
|
||||
};
|
||||
|
||||
/** Memory operation metadata.
|
||||
* This class holds the information about a memory operation. It lives
|
||||
* from initiateAcc to resource deallocation at commit or squash.
|
||||
@@ -1004,6 +1050,8 @@ class LSQ
|
||||
/** Another store port is in use */
|
||||
void cachePortBusy(bool is_load);
|
||||
|
||||
MasterPort &getDataPort() { return dcachePort; }
|
||||
|
||||
protected:
|
||||
/** D-cache is blocked */
|
||||
bool _cacheBlocked;
|
||||
@@ -1057,6 +1105,9 @@ class LSQ
|
||||
/** Max SQ Size - Used to Enforce Sharing Policies. */
|
||||
unsigned maxSQEntries;
|
||||
|
||||
/** Data port. */
|
||||
DcachePort dcachePort;
|
||||
|
||||
/** The LSQ units for individual threads. */
|
||||
std::vector<LSQUnit> thread;
|
||||
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
#include <string>
|
||||
|
||||
#include "base/logging.hh"
|
||||
#include "cpu/o3/cpu.hh"
|
||||
#include "cpu/o3/lsq.hh"
|
||||
#include "debug/Drain.hh"
|
||||
#include "debug/Fetch.hh"
|
||||
@@ -71,6 +72,7 @@ LSQ<Impl>::LSQ(O3CPU *cpu_ptr, IEW *iew_ptr, DerivO3CPUParams *params)
|
||||
params->smtLSQThreshold)),
|
||||
maxSQEntries(maxLSQAllocation(lsqPolicy, SQEntries, params->numThreads,
|
||||
params->smtLSQThreshold)),
|
||||
dcachePort(this, cpu_ptr),
|
||||
numThreads(params->numThreads)
|
||||
{
|
||||
assert(numThreads > 0 && numThreads <= Impl::MaxThreads);
|
||||
@@ -103,7 +105,7 @@ LSQ<Impl>::LSQ(O3CPU *cpu_ptr, IEW *iew_ptr, DerivO3CPUParams *params)
|
||||
for (ThreadID tid = 0; tid < numThreads; tid++) {
|
||||
thread.emplace_back(maxLQEntries, maxSQEntries);
|
||||
thread[tid].init(cpu, iew_ptr, params, this, tid);
|
||||
thread[tid].setDcachePort(&cpu_ptr->getDataPort());
|
||||
thread[tid].setDcachePort(&dcachePort);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1164,4 +1166,30 @@ LSQ<Impl>::SplitDataRequest::isCacheBlockHit(Addr blockAddr, Addr blockMask)
|
||||
return is_hit;
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
bool
|
||||
LSQ<Impl>::DcachePort::recvTimingResp(PacketPtr pkt)
|
||||
{
|
||||
return lsq->recvTimingResp(pkt);
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
void
|
||||
LSQ<Impl>::DcachePort::recvTimingSnoopReq(PacketPtr pkt)
|
||||
{
|
||||
for (ThreadID tid = 0; tid < cpu->numThreads; tid++) {
|
||||
if (cpu->getCpuAddrMonitor(tid)->doMonitor(pkt)) {
|
||||
cpu->wakeup(tid);
|
||||
}
|
||||
}
|
||||
lsq->recvTimingSnoopReq(pkt);
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
void
|
||||
LSQ<Impl>::DcachePort::recvReqRetry()
|
||||
{
|
||||
lsq->recvReqRetry();
|
||||
}
|
||||
|
||||
#endif//__CPU_O3_LSQ_IMPL_HH__
|
||||
|
||||
Reference in New Issue
Block a user