O3 CPU LSQ: Implement TSO

This patch makes O3's LSQ maintain total order between stores. Essentially
only the store at the head of the store buffer is allowed to be in flight.
Only after that store completes, the next store is issued to the memory
system. By default, the x86 architecture will have TSO.
This commit is contained in:
Nilay Vaish 2012-01-28 19:09:04 -06:00
parent 4acca8a053
commit 5c2fc35e02
3 changed files with 19 additions and 1 deletions

View file

@ -143,3 +143,5 @@ class DerivO3CPU(BaseCPU):
smtROBThreshold = Param.Int(100, "SMT ROB Threshold Sharing Parameter")
smtCommitPolicy = Param.String('RoundRobin', "SMT Commit Policy")
needsTSO = Param.Bool(buildEnv['TARGET_ISA'] == 'x86',
"Enable TSO Memory model")

View file

@ -453,6 +453,9 @@ class LSQUnit {
/** Has the blocked load been handled. */
bool loadBlockedHandled;
/** Whether or not a store is in flight. */
bool storeInFlight;
/** The sequence number of the blocked load. */
InstSeqNum blockedLoadSeqNum;
@ -466,6 +469,9 @@ class LSQUnit {
/** The packet that is pending free cache ports. */
PacketPtr pendingPkt;
/** Flag for memory model. */
bool needsTSO;
// Will also need how many read/write ports the Dcache has. Or keep track
// of that in stage that is one level up, and only call executeLoad/Store
// the appropriate number of times.

View file

@ -138,7 +138,7 @@ template <class Impl>
LSQUnit<Impl>::LSQUnit()
: loads(0), stores(0), storesToWB(0), cacheBlockMask(0), stalled(false),
isStoreBlocked(false), isLoadBlocked(false),
loadBlockedHandled(false), hasPendingPkt(false)
loadBlockedHandled(false), storeInFlight(false), hasPendingPkt(false)
{
}
@ -182,6 +182,7 @@ LSQUnit<Impl>::init(O3CPU *cpu_ptr, IEW *iew_ptr, DerivO3CPUParams *params,
memDepViolator = NULL;
blockedLoadSeqNum = 0;
needsTSO = params->needsTSO;
}
template<class Impl>
@ -770,6 +771,7 @@ LSQUnit<Impl>::writebackStores()
storeWBIdx != storeTail &&
storeQueue[storeWBIdx].inst &&
storeQueue[storeWBIdx].canWB &&
((!needsTSO) || (!storeInFlight)) &&
usedPorts < cachePorts) {
if (isStoreBlocked || lsq->cacheBlocked()) {
@ -1090,6 +1092,10 @@ LSQUnit<Impl>::storePostSend(PacketPtr pkt)
#endif
}
if (needsTSO) {
storeInFlight = true;
}
incrStIdx(storeWBIdx);
}
@ -1163,6 +1169,10 @@ LSQUnit<Impl>::completeStore(int store_idx)
storeQueue[store_idx].inst->setCompleted();
if (needsTSO) {
storeInFlight = false;
}
// Tell the checker we've completed this instruction. Some stores
// may get reported twice to the checker, but the checker can
// handle that case.