44 #ifndef __CPU_O3_LSQ_IMPL_HH__ 
   45 #define __CPU_O3_LSQ_IMPL_HH__ 
   52 #include "debug/Drain.hh" 
   53 #include "debug/Fetch.hh" 
   54 #include "debug/LSQ.hh" 
   55 #include "debug/Writeback.hh" 
   56 #include "params/DerivO3CPU.hh" 
   62     : cpu(cpu_ptr), iewStage(iew_ptr),
 
   63       LQEntries(params->LQEntries),
 
   64       SQEntries(params->SQEntries),
 
   65       numThreads(params->numThreads)
 
   72     std::string policy = params->smtLSQPolicy;
 
   75     std::transform(policy.begin(), policy.end(), policy.begin(),
 
   76                    (int(*)(int)) tolower);
 
   79     if (policy == 
"dynamic") {
 
   85         DPRINTF(
LSQ, 
"LSQ sharing policy set to Dynamic\n");
 
   86     } 
else if (policy == 
"partitioned") {
 
   93         DPRINTF(Fetch, 
"LSQ sharing policy set to Partitioned: " 
   94                 "%i entries per LQ | %i entries per SQ\n",
 
   96     } 
else if (policy == 
"threshold") {
 
   99         assert(params->smtLSQThreshold > 
LQEntries);
 
  100         assert(params->smtLSQThreshold > 
SQEntries);
 
  108         DPRINTF(
LSQ, 
"LSQ sharing policy set to Threshold: " 
  109                 "%i entries per LQ | %i entries per SQ\n",
 
  112         assert(0 && 
"Invalid LSQ Sharing Policy.Options Are:{Dynamic," 
  113                     "Partitioned, Threshold}");
 
  130     return iewStage->name() + 
".lsq";
 
  138     for (
ThreadID tid = 0; tid < numThreads; tid++) {
 
  139         thread[tid].regStats();
 
  147     activeThreads = at_ptr;
 
  148     assert(activeThreads != 0);
 
  151 template <
class Impl>
 
  157     for (
ThreadID tid = 0; tid < numThreads; tid++)
 
  158         thread[tid].drainSanityCheck();
 
  161 template <
class Impl>
 
  168         DPRINTF(Drain, 
"Not drained, LQ not empty.\n");
 
  173         DPRINTF(Drain, 
"Not drained, SQ not empty.\n");
 
  180 template <
class Impl>
 
  184     for (
ThreadID tid = 0; tid < numThreads; tid++) {
 
  185         thread[tid].takeOverFrom();
 
  189 template <
class Impl>
 
  193     if (lsqPolicy == Partitioned) {
 
  194         return LQEntries / num_threads;
 
  200 template <
class Impl>
 
  204     if (lsqPolicy != Dynamic || numThreads > 1) {
 
  205         int active_threads = activeThreads->size();
 
  209         if (lsqPolicy == Partitioned) {
 
  210             maxEntries = LQEntries / active_threads;
 
  211         } 
else if (lsqPolicy == Threshold && active_threads == 1) {
 
  212             maxEntries = LQEntries;
 
  214             maxEntries = LQEntries;
 
  220         while (threads != end) {
 
  223             resizeEntries(maxEntries, tid);
 
  232     thread[tid].clearLQ();
 
  233     thread[tid].clearSQ();
 
  240     thread[tid].resizeLQ(size);
 
  241     thread[tid].resizeSQ(size);
 
  251     while (threads != end) {
 
  262     ThreadID tid = load_inst->threadNumber;
 
  264     thread[tid].insertLoad(load_inst);
 
  271     ThreadID tid = store_inst->threadNumber;
 
  273     thread[tid].insertStore(store_inst);
 
  282     return thread[tid].executeLoad(inst);
 
  291     return thread[tid].executeStore(inst);
 
  301     while (threads != end) {
 
  304         if (numStoresToWB(tid) > 0) {
 
  305             DPRINTF(Writeback,
"[tid:%i] Writing back stores. %i stores " 
  306                 "available for Writeback.\n", tid, numStoresToWB(tid));
 
  309         thread[tid].writebackStores();
 
  321     while (threads != end) {
 
  324         if (thread[tid].violation())
 
  331 template <
class Impl>
 
  335     iewStage->cacheUnblocked();
 
  337     for (
ThreadID tid : *activeThreads) {
 
  338         thread[tid].recvRetry();
 
  342 template <
class Impl>
 
  347         DPRINTF(
LSQ, 
"Got error packet back for address: %#X\n",
 
  351         .completeDataAccess(pkt);
 
  365         DPRINTF(
LSQ, 
"received invalidation with response for addr:%#x\n",
 
  368         for (
ThreadID tid = 0; tid < numThreads; tid++) {
 
  369             thread[tid].checkSnoop(pkt);
 
  378 template <
class Impl>
 
  387         DPRINTF(
LSQ, 
"received invalidation for addr:%#x\n",
 
  389         for (
ThreadID tid = 0; tid < numThreads; tid++) {
 
  390             thread[tid].checkSnoop(pkt);
 
  404     while (threads != end) {
 
  407         total += getCount(tid);
 
  422     while (threads != end) {
 
  425         total += numLoads(tid);
 
  440     while (threads != end) {
 
  443         total += thread[tid].numStores();
 
  458     while (threads != end) {
 
  461         total += thread[tid].numFreeLoadEntries();
 
  476     while (threads != end) {
 
  479         total += thread[tid].numFreeStoreEntries();
 
  489         return thread[tid].numFreeLoadEntries();
 
  496         return thread[tid].numFreeStoreEntries();
 
  506     while (threads != end) {
 
  509         if (!(thread[tid].lqFull() || thread[tid].sqFull()))
 
  522     if (lsqPolicy == Dynamic)
 
  525         return thread[tid].lqFull() || thread[tid].sqFull();
 
  532     return lqEmpty() && sqEmpty();
 
  542     while (threads != end) {
 
  545         if (!thread[tid].lqEmpty())
 
  559     while (threads != end) {
 
  562         if (!thread[tid].sqEmpty())
 
  576     while (threads != end) {
 
  579         if (!thread[tid].lqFull())
 
  592     if (lsqPolicy == Dynamic)
 
  595         return thread[tid].lqFull();
 
  605     while (threads != end) {
 
  621     if (lsqPolicy == Dynamic)
 
  624         return thread[tid].sqFull();
 
  634     while (threads != end) {
 
  637         if (!thread[tid].isStalled())
 
  648     if (lsqPolicy == Dynamic)
 
  651         return thread[tid].isStalled();
 
  661     while (threads != end) {
 
  664         if (hasStoresToWB(tid))
 
  678     while (threads != end) {
 
  695     while (threads != end) {
 
  698         thread[tid].dumpInsts();
 
  702 #endif//__CPU_O3_LSQ_IMPL_HH__ 
unsigned SQEntries
Total Size of SQ Entries. 
 
void takeOverFrom()
Takes over execution from another CPU's thread. 
 
void resetEntries()
Reset the max entries for each thread. 
 
ThreadID numThreads
Number of Threads. 
 
Impl::DynInstPtr DynInstPtr
 
unsigned LQEntries
Total Size of LQ Entries. 
 
bool willWB()
Returns if the LSQ will write back to memory this cycle. 
 
ContextID contextId() const 
Accessor function for context ID. 
 
unsigned maxSQEntries
Max SQ Size - Used to Enforce Sharing Policies. 
 
void dumpInsts() const 
Debugging function to print out all instructions. 
 
void removeEntries(ThreadID tid)
 
void tick()
Ticks the LSQ. 
 
bool sqFull()
Returns if any of the SQs are full. 
 
std::string name() const 
Returns the name of the LSQ. 
 
bool violation()
Returns whether or not there was a memory ordering violation. 
 
bool hasStoresToWB()
Returns whether or not there are any stores to write back to memory. 
 
Fault executeLoad(DynInstPtr &inst)
Executes a load. 
 
bool isFull()
Returns if the LSQ is full (either LQ or SQ is full). 
 
void writebackStores()
Attempts to write back stores until all cache ports are used or the interface becomes blocked...
 
void drainSanityCheck() const 
Perform sanity checks after a drain. 
 
void init(O3CPU *cpu_ptr, IEW *iew_ptr, DerivO3CPUParams *params, LSQ *lsq_ptr, unsigned maxLQEntries, unsigned maxSQEntries, unsigned id)
Initializes the LSQ unit with the specified number of entries. 
 
unsigned numFreeStoreEntries()
Returns the number of free store entries. 
 
void insertStore(DynInstPtr &store_inst)
Inserts a store into the LSQ. 
 
void resizeEntries(unsigned size, ThreadID tid)
Resize the max entries for a thread. 
 
int numLoads()
Returns the total number of loads in the load queue. 
 
void insertLoad(DynInstPtr &load_inst)
Inserts a load into the LSQ. 
 
Fault executeStore(DynInstPtr &inst)
Executes a store. 
 
unsigned maxLQEntries
Max LQ Size - Used to Enforce Sharing Policies. 
 
const RequestPtr req
A pointer to the original request. 
 
void setDcachePort(MasterPort *dcache_port)
Sets the pointer to the dcache port. 
 
LSQUnit * thread
The LSQ units for individual threads. 
 
A Packet is used to encapsulate a transfer between two objects in the memory system (e...
 
const FlagsType total
Print the total. 
 
int getCount()
Returns the number of instructions in all of the queues. 
 
int16_t ThreadID
Thread index/ID type. 
 
unsigned numFreeLoadEntries()
Returns the number of free load entries. 
 
int entryAmount(ThreadID num_threads)
Number of entries needed for the given amount of threads. 
 
void recvReqRetry()
Retry the previous send that failed. 
 
LSQPolicy lsqPolicy
The LSQ policy for SMT mode. 
 
const std::string & cmdString() const 
Return the string name of the cmd field (for debugging and tracing). 
 
void setActiveThreads(std::list< ThreadID > *at_ptr)
Sets the pointer to the list of active threads. 
 
bool isEmpty() const 
Returns if the LSQ is empty (both LQ and SQ are empty). 
 
bool sqEmpty() const 
Returns if all of the SQs are empty. 
 
LSQ(O3CPU *cpu_ptr, IEW *iew_ptr, DerivO3CPUParams *params)
Constructs an LSQ with the given parameters. 
 
int numStores()
Returns the total number of stores in the store queue. 
 
bool isDrained() const 
Has the LSQ drained? 
 
void regStats()
Registers statistics of each LSQ unit. 
 
bool recvTimingResp(PacketPtr pkt)
Handles writing back and completing the load or store that has returned from memory. 
 
bool isInvalidate() const 
 
Class that implements the actual LQ and SQ for each specific thread. 
 
O3CPU * cpu
The CPU pointer. 
 
bool lqEmpty() const 
Returns if all of the LQs are empty. 
 
bool isStalled()
Returns if the LSQ is stalled due to a memory operation that must be replayed. 
 
void recvTimingSnoopReq(PacketPtr pkt)
 
std::shared_ptr< FaultBase > Fault
 
bool lqFull()
Returns if any of the LQs are full.