/*
- * Copyright (c) 2004-2006 The Regents of The University of Michigan
+ * Copyright (c) 2005-2006 The Regents of The University of Michigan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
*/
#include <algorithm>
+#include <list>
#include <string>
#include "cpu/o3/lsq.hh"
-using namespace std;
+template <class Impl>
+Tick
+LSQ<Impl>::DcachePort::recvAtomic(PacketPtr pkt)
+{
+ panic("O3CPU model does not work with atomic mode!");
+ return curTick;
+}
+
+template <class Impl>
+void
+LSQ<Impl>::DcachePort::recvFunctional(PacketPtr pkt)
+{
+ DPRINTF(LSQ, "LSQ doesn't update things on a recvFunctional.");
+}
+
+template <class Impl>
+void
+LSQ<Impl>::DcachePort::recvStatusChange(Status status)
+{
+ if (status == RangeChange) {
+ if (!snoopRangeSent) {
+ snoopRangeSent = true;
+ sendStatusChange(Port::RangeChange);
+ }
+ return;
+ }
+ panic("O3CPU doesn't expect recvStatusChange callback!");
+}
+
+template <class Impl>
+bool
+LSQ<Impl>::DcachePort::recvTiming(PacketPtr pkt)
+{
+ if (pkt->isResponse()) {
+ lsq->thread[pkt->req->getThreadNum()].completeDataAccess(pkt);
+ }
+ else {
+ //else it is a coherence request, maybe you need to do something
+ warn("Recieved a coherence request (Invalidate?), 03CPU doesn't"
+ "update LSQ for these\n");
+ }
+ return true;
+}
+
+template <class Impl>
+void
+LSQ<Impl>::DcachePort::recvRetry()
+{
+ if (lsq->retryTid == -1)
+ {
+ //Squashed, so drop it
+ return;
+ }
+ lsq->thread[lsq->retryTid].recvRetry();
+ // Speculatively clear the retry Tid. This will get set again if
+ // the LSQUnit was unable to complete its access.
+ lsq->retryTid = -1;
+}
template <class Impl>
LSQ<Impl>::LSQ(Params *params)
- : LQEntries(params->LQEntries), SQEntries(params->SQEntries),
- numThreads(params->numberOfThreads)
+ : dcachePort(this), LQEntries(params->LQEntries),
+ SQEntries(params->SQEntries), numThreads(params->numberOfThreads),
+ retryTid(-1)
{
DPRINTF(LSQ, "Creating LSQ object.\n");
+ dcachePort.snoopRangeSent = false;
+
//**********************************************/
//************ Handle SMT Parameters ***********/
//**********************************************/
- string policy = params->smtLSQPolicy;
+ std::string policy = params->smtLSQPolicy;
//Convert string to lowercase
std::transform(policy.begin(), policy.end(), policy.begin(),
//Initialize LSQs
for (int tid=0; tid < numThreads; tid++) {
- thread[tid].init(params, maxLQEntries, maxSQEntries, tid);
+ thread[tid].init(params, this, maxLQEntries, maxSQEntries, tid);
+ thread[tid].setDcachePort(&dcachePort);
}
}
template<class Impl>
void
-LSQ<Impl>::setActiveThreads(list<unsigned> *at_ptr)
+LSQ<Impl>::regStats()
+{
+ //Initialize LSQs
+ for (int tid=0; tid < numThreads; tid++) {
+ thread[tid].regStats();
+ }
+}
+
+template<class Impl>
+void
+LSQ<Impl>::setActiveThreads(std::list<unsigned> *at_ptr)
{
activeThreads = at_ptr;
assert(activeThreads != 0);
template<class Impl>
void
-LSQ<Impl>::setCPU(FullCPU *cpu_ptr)
+LSQ<Impl>::setCPU(O3CPU *cpu_ptr)
{
cpu = cpu_ptr;
+ dcachePort.setName(name());
+
for (int tid=0; tid < numThreads; tid++) {
thread[tid].setCPU(cpu_ptr);
}
LSQ<Impl>::resetEntries()
{
if (lsqPolicy != Dynamic || numThreads > 1) {
- int active_threads = (*activeThreads).size();
-
- list<unsigned>::iterator threads = (*activeThreads).begin();
- list<unsigned>::iterator list_end = (*activeThreads).end();
+ int active_threads = activeThreads->size();
int maxEntries;
maxEntries = LQEntries;
}
- while (threads != list_end) {
- resizeEntries(maxEntries,*threads++);
+ std::list<unsigned>::iterator threads = activeThreads->begin();
+ std::list<unsigned>::iterator end = activeThreads->end();
+
+ while (threads != end) {
+ unsigned tid = *threads++;
+
+ resizeEntries(maxEntries, tid);
}
}
}
void
LSQ<Impl>::tick()
{
- list<unsigned>::iterator active_threads = (*activeThreads).begin();
+ std::list<unsigned>::iterator threads = activeThreads->begin();
+ std::list<unsigned>::iterator end = activeThreads->end();
- while (active_threads != (*activeThreads).end()) {
- unsigned tid = *active_threads++;
+ while (threads != end) {
+ unsigned tid = *threads++;
thread[tid].tick();
}
void
LSQ<Impl>::writebackStores()
{
- list<unsigned>::iterator active_threads = (*activeThreads).begin();
+ std::list<unsigned>::iterator threads = activeThreads->begin();
+ std::list<unsigned>::iterator end = activeThreads->end();
- while (active_threads != (*activeThreads).end()) {
- unsigned tid = *active_threads++;
+ while (threads != end) {
+ unsigned tid = *threads++;
if (numStoresToWB(tid) > 0) {
DPRINTF(Writeback,"[tid:%i] Writing back stores. %i stores "
LSQ<Impl>::violation()
{
/* Answers: Does Anybody Have a Violation?*/
- list<unsigned>::iterator active_threads = (*activeThreads).begin();
+ std::list<unsigned>::iterator threads = activeThreads->begin();
+ std::list<unsigned>::iterator end = activeThreads->end();
+
+ while (threads != end) {
+ unsigned tid = *threads++;
- while (active_threads != (*activeThreads).end()) {
- unsigned tid = *active_threads++;
if (thread[tid].violation())
return true;
}
{
unsigned total = 0;
- list<unsigned>::iterator active_threads = (*activeThreads).begin();
+ std::list<unsigned>::iterator threads = activeThreads->begin();
+ std::list<unsigned>::iterator end = activeThreads->end();
+
+ while (threads != end) {
+ unsigned tid = *threads++;
- while (active_threads != (*activeThreads).end()) {
- unsigned tid = *active_threads++;
total += getCount(tid);
}
{
unsigned total = 0;
- list<unsigned>::iterator active_threads = (*activeThreads).begin();
+ std::list<unsigned>::iterator threads = activeThreads->begin();
+ std::list<unsigned>::iterator end = activeThreads->end();
+
+ while (threads != end) {
+ unsigned tid = *threads++;
- while (active_threads != (*activeThreads).end()) {
- unsigned tid = *active_threads++;
total += numLoads(tid);
}
{
unsigned total = 0;
- list<unsigned>::iterator active_threads = (*activeThreads).begin();
+ std::list<unsigned>::iterator threads = activeThreads->begin();
+ std::list<unsigned>::iterator end = activeThreads->end();
+
+ while (threads != end) {
+ unsigned tid = *threads++;
- while (active_threads != (*activeThreads).end()) {
- unsigned tid = *active_threads++;
total += thread[tid].numStores();
}
{
unsigned total = 0;
- list<unsigned>::iterator active_threads = (*activeThreads).begin();
+ std::list<unsigned>::iterator threads = activeThreads->begin();
+ std::list<unsigned>::iterator end = activeThreads->end();
+
+ while (threads != end) {
+ unsigned tid = *threads++;
- while (active_threads != (*activeThreads).end()) {
- unsigned tid = *active_threads++;
total += thread[tid].numLoadsReady();
}
{
unsigned total = 0;
- list<unsigned>::iterator active_threads = (*activeThreads).begin();
+ std::list<unsigned>::iterator threads = activeThreads->begin();
+ std::list<unsigned>::iterator end = activeThreads->end();
+
+ while (threads != end) {
+ unsigned tid = *threads++;
- while (active_threads != (*activeThreads).end()) {
- unsigned tid = *active_threads++;
total += thread[tid].numFreeEntries();
}
unsigned
LSQ<Impl>::numFreeEntries(unsigned tid)
{
- //if( lsqPolicy == Dynamic )
+ //if (lsqPolicy == Dynamic)
//return numFreeEntries();
//else
return thread[tid].numFreeEntries();
bool
LSQ<Impl>::isFull()
{
- list<unsigned>::iterator active_threads = (*activeThreads).begin();
+ std::list<unsigned>::iterator threads = activeThreads->begin();
+ std::list<unsigned>::iterator end = activeThreads->end();
+
+ while (threads != end) {
+ unsigned tid = *threads++;
- while (active_threads != (*activeThreads).end()) {
- unsigned tid = *active_threads++;
- if (! (thread[tid].lqFull() || thread[tid].sqFull()) )
+ if (!(thread[tid].lqFull() || thread[tid].sqFull()))
return false;
}
{
//@todo: Change to Calculate All Entries for
//Dynamic Policy
- if( lsqPolicy == Dynamic )
+ if (lsqPolicy == Dynamic)
return isFull();
else
return thread[tid].lqFull() || thread[tid].sqFull();
bool
LSQ<Impl>::lqFull()
{
- list<unsigned>::iterator active_threads = (*activeThreads).begin();
+ std::list<unsigned>::iterator threads = activeThreads->begin();
+ std::list<unsigned>::iterator end = activeThreads->end();
+
+ while (threads != end) {
+ unsigned tid = *threads++;
- while (active_threads != (*activeThreads).end()) {
- unsigned tid = *active_threads++;
if (!thread[tid].lqFull())
return false;
}
{
//@todo: Change to Calculate All Entries for
//Dynamic Policy
- if( lsqPolicy == Dynamic )
+ if (lsqPolicy == Dynamic)
return lqFull();
else
return thread[tid].lqFull();
bool
LSQ<Impl>::sqFull()
{
- list<unsigned>::iterator active_threads = (*activeThreads).begin();
+ std::list<unsigned>::iterator threads = activeThreads->begin();
+ std::list<unsigned>::iterator end = activeThreads->end();
+
+ while (threads != end) {
+ unsigned tid = *threads++;
- while (active_threads != (*activeThreads).end()) {
- unsigned tid = *active_threads++;
if (!sqFull(tid))
return false;
}
{
//@todo: Change to Calculate All Entries for
//Dynamic Policy
- if( lsqPolicy == Dynamic )
+ if (lsqPolicy == Dynamic)
return sqFull();
else
return thread[tid].sqFull();
bool
LSQ<Impl>::isStalled()
{
- list<unsigned>::iterator active_threads = (*activeThreads).begin();
+ std::list<unsigned>::iterator threads = activeThreads->begin();
+ std::list<unsigned>::iterator end = activeThreads->end();
+
+ while (threads != end) {
+ unsigned tid = *threads++;
- while (active_threads != (*activeThreads).end()) {
- unsigned tid = *active_threads++;
if (!thread[tid].isStalled())
return false;
}
bool
LSQ<Impl>::isStalled(unsigned tid)
{
- if( lsqPolicy == Dynamic )
+ if (lsqPolicy == Dynamic)
return isStalled();
else
return thread[tid].isStalled();
bool
LSQ<Impl>::hasStoresToWB()
{
- list<unsigned>::iterator active_threads = (*activeThreads).begin();
+ std::list<unsigned>::iterator threads = activeThreads->begin();
+ std::list<unsigned>::iterator end = activeThreads->end();
+
+ if (threads == end)
+ return false;
+
+ while (threads != end) {
+ unsigned tid = *threads++;
- while (active_threads != (*activeThreads).end()) {
- unsigned tid = *active_threads++;
if (!hasStoresToWB(tid))
return false;
}
bool
LSQ<Impl>::willWB()
{
- list<unsigned>::iterator active_threads = (*activeThreads).begin();
+ std::list<unsigned>::iterator threads = activeThreads->begin();
+ std::list<unsigned>::iterator end = activeThreads->end();
+
+ while (threads != end) {
+ unsigned tid = *threads++;
- while (active_threads != (*activeThreads).end()) {
- unsigned tid = *active_threads++;
if (!willWB(tid))
return false;
}
void
LSQ<Impl>::dumpInsts()
{
- list<unsigned>::iterator active_threads = (*activeThreads).begin();
+ std::list<unsigned>::iterator threads = activeThreads->begin();
+ std::list<unsigned>::iterator end = activeThreads->end();
+
+ while (threads != end) {
+ unsigned tid = *threads++;
- while (active_threads != (*activeThreads).end()) {
- unsigned tid = *active_threads++;
thread[tid].dumpInsts();
}
}