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:
Gabe Black
2019-08-17 01:15:39 -07:00
parent c387a212d9
commit b4e3e2f4a4
5 changed files with 86 additions and 76 deletions

View File

@@ -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),

View File

@@ -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;

View File

@@ -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);

View File

@@ -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;

View File

@@ -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__