50#include "debug/Activity.hh"
51#include "debug/HtmCpu.hh"
52#include "debug/IEW.hh"
53#include "debug/LSQUnit.hh"
54#include "debug/O3PipeView.hh"
66 :
Event(Default_Pri, AutoDelete),
67 inst(_inst), pkt(_pkt), lsqPtr(lsq_ptr)
69 assert(_inst->savedRequest);
70 _inst->savedRequest->writebackScheduled();
76 assert(!lsqPtr->cpu->switchedOut());
78 lsqPtr->writeback(inst, pkt);
80 assert(inst->savedRequest);
81 inst->savedRequest->writebackDone();
88 return "Store writeback";
95 assert(request !=
nullptr);
127 "store notification (ignored) of HTM transaction failure "
128 "in cache - addr=0x%lx - rc=%s - htmUid=%d\n",
145 panic(
"HTM error - unhandled return code from cache (%s)",
150 std::make_shared<GenericHtmFailureFault>(
151 inst->getHtmTransactionUid(),
155 "load notification of HTM transaction failure "
156 "in cache - pc=%s - addr=0x%lx - "
157 "rc=%u - htmUid=%d\n",
158 inst->pcState(), pkt->
getAddr(),
166 if (!inst->isSquashed()) {
170 assert(inst->isLoad() || inst->isStoreConditional() ||
180 if (inst->isStore() || inst->isAtomic()) {
184 }
else if (inst->isStore()) {
204 LSQ *lsq_ptr,
unsigned id)
255 : statistics::
Group(parent),
256 ADD_STAT(forwLoads, statistics::units::Count::get(),
257 "Number of loads that had data forwarded from stores"),
258 ADD_STAT(squashedLoads, statistics::units::Count::get(),
259 "Number of loads squashed"),
260 ADD_STAT(ignoredResponses, statistics::units::Count::get(),
261 "Number of memory responses ignored because the instruction is "
263 ADD_STAT(memOrderViolation, statistics::units::Count::get(),
264 "Number of memory ordering violations"),
265 ADD_STAT(squashedStores, statistics::units::Count::get(),
266 "Number of stores squashed"),
267 ADD_STAT(rescheduledLoads, statistics::units::Count::get(),
268 "Number of loads that were rescheduled"),
269 ADD_STAT(blockedByCache, statistics::units::Count::get(),
270 "Number of times an access to memory failed due to the cache "
272 ADD_STAT(loadToUse,
"Distribution of cycle latency between the "
273 "first time a load is issued and its completion")
305 assert(inst->isMemRef());
307 assert(inst->isLoad() || inst->isStore() || inst->isAtomic());
309 if (inst->isLoad()) {
335 assert(load_inst->lqIdx > 0);
341 if (load_inst->isHtmStart()) {
343 DPRINTF(HtmCpu,
">> htmStarts++ (%d) : htmStops (%d)\n",
348 auto htm_uid = htm_cpt->getHtmUid();
351 if (!load_inst->inHtmTransactionalState()) {
352 htm_uid = htm_cpt->newHtmUid();
353 DPRINTF(HtmCpu,
"generating new htmUid=%u\n", htm_uid);
354 if (htm_depth != 1) {
356 "unusual HTM transactional depth (%d)"
357 " possibly caused by mispeculation - htmUid=%u\n",
361 load_inst->setHtmTransactionalState(htm_uid, htm_depth);
364 if (load_inst->isHtmStop()) {
366 DPRINTF(HtmCpu,
">> htmStarts (%d) : htmStops++ (%d)\n",
371 "htmStops==1 && htmStarts==0. "
372 "This generally shouldn't happen "
373 "(unless due to misspeculation)\n");
393 assert(store_inst->lqIdx > 0);
436 bool no_squash =
cpu->
thread[
x]->noSquashFromTC;
454 if (ld_inst->effAddrValid() && request &&
457 ld_inst->tcBase()->getIsaPtr()->handleLockedSnoopHit(ld_inst.
get());
460 bool force_squash =
false;
463 ld_inst = iter->instruction();
465 request = iter->request();
466 if (!ld_inst->effAddrValid() || ld_inst->strictlyOrdered() || !request)
470 ld_inst->seqNum, invalidate_addr);
480 if (ld_inst->possibleLoadViolation() || force_squash) {
482 pkt->
getAddr(), ld_inst->seqNum);
485 ld_inst->fault = std::make_shared<ReExec>();
489 pkt->
getAddr(), ld_inst->seqNum);
495 ld_inst->tcBase()->getIsaPtr()->
496 handleLockedSnoopHit(ld_inst.
get());
502 ld_inst->hitExternalSnoop(
true);
523 if (!ld_inst->effAddrValid() || ld_inst->strictlyOrdered()) {
532 if (inst_eff_addr2 >= ld_eff_addr1 && inst_eff_addr1 <= ld_eff_addr2) {
533 if (inst->isLoad()) {
537 if (ld_inst->hitExternalSnoop()) {
541 "and [sn:%lli] at address %#x\n",
542 inst->seqNum, ld_inst->seqNum, ld_eff_addr1);
547 return std::make_shared<GenericISA::M5PanicFault>(
548 "Detected fault with inst [sn:%lli] and "
549 "[sn:%lli] at address %#x\n",
550 inst->seqNum, ld_inst->seqNum, ld_eff_addr1);
556 ld_inst->possibleLoadViolation(
true);
558 " between instructions [sn:%lli] and [sn:%lli]\n",
559 inst_eff_addr1, inst->seqNum, ld_inst->seqNum);
568 "[sn:%lli] at address %#x\n",
569 inst->seqNum, ld_inst->seqNum, ld_eff_addr1);
574 return std::make_shared<GenericISA::M5PanicFault>(
575 "Detected fault with "
576 "inst [sn:%lli] and [sn:%lli] at address %#x\n",
577 inst->seqNum, ld_inst->seqNum, ld_eff_addr1);
596 inst->pcState(), inst->seqNum);
598 assert(!inst->isSquashed());
600 load_fault = inst->initiateAcc();
602 if (load_fault ==
NoFault && !inst->readMemAccPredicate()) {
603 assert(inst->readPredicate());
605 inst->completeAcc(
nullptr);
611 if (inst->isTranslationDelayed() && load_fault ==
NoFault)
614 if (load_fault !=
NoFault && inst->translationCompleted() &&
615 inst->savedRequest->isPartialFault()
616 && !inst->savedRequest->isComplete()) {
617 assert(inst->savedRequest->isSplit());
627 if (load_fault !=
NoFault || !inst->readPredicate()) {
632 if (!inst->readPredicate())
633 inst->forwardOldRegs();
636 (load_fault !=
NoFault ?
"fault" :
"predication"));
637 if (!(inst->hasRequest() && inst->strictlyOrdered()) ||
638 inst->isAtCommit()) {
644 if (inst->effAddrValid()) {
645 auto it = inst->lqIt;
662 ssize_t store_idx = store_inst->sqIdx;
665 store_inst->pcState(), store_inst->seqNum);
667 assert(!store_inst->isSquashed());
671 typename LoadQueue::iterator loadIt = store_inst->lqIt;
673 Fault store_fault = store_inst->initiateAcc();
675 if (store_inst->isTranslationDelayed() &&
679 if (!store_inst->readPredicate()) {
680 DPRINTF(
LSQUnit,
"Store [sn:%lli] not executed from predication\n",
682 store_inst->forwardOldRegs();
688 store_inst->pcState(), store_inst->seqNum);
690 if (store_inst->isAtomic()) {
693 if (!(store_inst->hasRequest() && store_inst->strictlyOrdered()) ||
694 store_inst->isAtCommit()) {
695 store_inst->setExecuted();
704 assert(store_fault ==
NoFault);
706 if (store_inst->isStoreConditional() || store_inst->isAtomic()) {
730 if (!inst->isInstPrefetch() && !inst->isDataPrefetch()
731 && inst->firstIssue != -1
732 && inst->lastWakeDependents != -1) {
734 inst->lastWakeDependents - inst->firstIssue));
763 if (
x.instruction()->seqNum > youngest_inst) {
768 x.instruction()->pcState(),
769 x.instruction()->seqNum);
782 storeWBIt->request()->sendPacketToCache();
819 if (
storeWBIt->instruction()->isDataPrefetch()) {
832 if ((request->
mainReq()->isLLSC() ||
833 request->
mainReq()->isRelease()) &&
836 "[sn:%lli] is %s%s and not head of the queue\n",
838 request->
mainReq()->getPaddr(), inst->seqNum,
839 request->
mainReq()->isLLSC() ?
"SC" :
"",
840 request->
mainReq()->isRelease() ?
"/Release" :
"");
846 assert(!inst->memData);
847 inst->memData =
new uint8_t[request->
_size];
850 memset(inst->memData, 0, request->
_size);
857 "to Addr:%#x, data:%#x [sn:%lli]\n",
859 request->
mainReq()->getPaddr(), (
int)*(inst->memData),
863 if (inst->isStoreConditional()) {
867 inst->recordResult(
false);
868 bool success = inst->tcBase()->getIsaPtr()->handleLockedWrite(
870 inst->recordResult(
true);
877 "Instantly completing it.\n",
892 if (request->
mainReq()->isLocalAccess()) {
893 assert(!inst->isStoreConditional());
894 assert(!inst->inHtmTransactionalState());
899 request->
mainReq()->localAccessor(thread, main_pkt);
912 DPRINTF(
LSQUnit,
"D-Cache became blocked when writing [sn:%lli], "
913 "will retry later\n",
946 DPRINTF(HtmCpu,
">> htmStarts-- (%d) : htmStops (%d)\n",
952 DPRINTF(HtmCpu,
">> htmStarts (%d) : htmStops-- (%d)\n",
966 uint64_t in_flight_uid = 0;
968 if (scan_it->instruction()->isHtmStart() &&
969 !scan_it->instruction()->isSquashed()) {
970 in_flight_uid = scan_it->instruction()->getHtmTransactionUid();
971 DPRINTF(HtmCpu,
"loadQueue[%d]: found valid HtmStart htmUid=%u\n",
972 scan_it._idx, in_flight_uid);
980 const uint64_t old_local_htm_uid = htm_cpt->getHtmUid();
981 uint64_t new_local_htm_uid;
982 if (in_flight_uid > 0)
983 new_local_htm_uid = in_flight_uid;
987 if (old_local_htm_uid != new_local_htm_uid) {
988 DPRINTF(HtmCpu,
"flush: lastRetiredHtmUid=%u\n",
990 DPRINTF(HtmCpu,
"flush: resetting localHtmUid=%u\n",
993 htm_cpt->setHtmUid(new_local_htm_uid);
1009 "idx:%i [sn:%lli]\n",
1017 panic(
"Is stalled should have been cleared by stalling load!\n");
1039 return htm_cpt->getHtmUid();
1055 if (!
storeWBIt->instruction()->isStoreConditional()) {
1059 storeWBIt->instruction()->setCompleted();
1079 if (inst->isSquashed()) {
1080 assert (!inst->isStore() || inst->isStoreConditional());
1085 if (!inst->isExecuted()) {
1086 inst->setExecuted();
1090 inst->completeAcc(pkt);
1100 auto htm_fault = std::dynamic_pointer_cast<
1104 assert(
dynamic_cast<ReExec*
>(inst->fault.
get()) !=
nullptr ||
1105 inst->savedRequest->isPartialFault());
1113 "%s writeback with HTM failure fault, "
1114 "however, completing packet is not aware of "
1115 "transaction failure. cause=%s htmUid=%u\n",
1116 inst->staticInst->getName(),
1118 htm_fault->getHtmUid());
1122 "due to pending fault.\n", inst->seqNum);
1138 assert(store_idx->valid());
1139 store_idx->completed() =
true;
1149 DynInstPtr store_inst = store_idx->instruction();
1160 DPRINTF(
LSQUnit,
"Completing store [sn:%lli], idx:%i, store head "
1165 if (debug::O3PipeView) {
1166 store_inst->storeTick =
1167 curTick() - store_inst->fetchTick;
1181 store_inst->setCompleted();
1193 if (
cpu->
checker && !store_inst->isStoreConditional()) {
1202 bool cache_got_blocked =
false;
1210 cache_got_blocked =
true;
1223 if (cache_got_blocked) {
1228 assert(request ==
storeWBIt->request());
1233 DPRINTF(
LSQUnit,
"Memory request (pkt: %s) from inst [sn:%llu] was"
1234 " %ssent (cache is blocked: %d, cache_got_blocked: %d)\n",
1243 DPRINTF(
LSQUnit,
"Unit %p marking stale translations %d %d\n",
this,
1246 if (entry.valid() && entry.hasRequest())
1247 entry.request()->markAsStaleTranslation();
1250 if (entry.valid() && entry.hasRequest())
1251 entry.request()->markAsStaleTranslation();
1260 if (entry.valid() && entry.hasRequest()
1261 && entry.request()->hasStaleTranslation())
1265 if (entry.valid() && entry.hasRequest()
1266 && entry.request()->hasStaleTranslation())
1285 cprintf(
"Load store queue: Dumping instructions.\n");
1291 cprintf(
"%s.[sn:%llu] ", inst->pcState(), inst->seqNum);
1300 cprintf(
"%s.[sn:%llu] ", inst->pcState(), inst->seqNum);
1325 assert(!load_inst->isExecuted());
1332 if (request->
mainReq()->isStrictlyOrdered() &&
1333 (load_idx !=
loadQueue.
head() || !load_inst->isAtCommit())) {
1337 load_inst->clearIssued();
1338 load_inst->effAddrValid(
false);
1341 load_inst->seqNum, load_inst->pcState());
1348 return std::make_shared<GenericISA::M5PanicFault>(
1349 "Strictly ordered load [sn:%llx] PC %s\n",
1350 load_inst->seqNum, load_inst->pcState());
1354 "storeHead: %i addr: %#x%s\n",
1359 if (request->
mainReq()->isLLSC()) {
1363 load_inst->recordResult(
false);
1364 load_inst->tcBase()->getIsaPtr()->handleLockedRead(load_inst.
get(),
1366 load_inst->recordResult(
true);
1369 if (request->
mainReq()->isLocalAccess()) {
1370 assert(!load_inst->memData);
1378 Cycles delay = request->
mainReq()->localAccessor(thread, main_pkt);
1386 auto store_it = load_inst->sqIt;
1389 while (store_it !=
storeWBIt && !load_inst->isDataPrefetch()) {
1392 assert(store_it->valid());
1393 assert(store_it->instruction()->seqNum < load_inst->seqNum);
1394 int store_size = store_it->size();
1399 if (store_size != 0 && !store_it->instruction()->strictlyOrdered() &&
1400 !(store_it->request()->mainReq() &&
1401 store_it->request()->mainReq()->isCacheMaintenance())) {
1402 assert(store_it->instruction()->effAddrValid());
1406 auto req_s = request->
mainReq()->getVaddr();
1407 auto req_e = req_s + request->
mainReq()->getSize();
1408 auto st_s = store_it->instruction()->effAddr;
1409 auto st_e = st_s + store_size;
1411 bool store_has_lower_limit = req_s >= st_s;
1412 bool store_has_upper_limit = req_e <= st_e;
1413 bool lower_load_has_store_part = req_s < st_e;
1414 bool upper_load_has_store_part = req_e > st_s;
1422 if (!store_it->instruction()->isAtomic() &&
1423 store_has_lower_limit && store_has_upper_limit &&
1424 !request->
mainReq()->isLLSC()) {
1426 const auto& store_req = store_it->request()->mainReq();
1427 coverage = store_req->isMasked() ?
1433 (!request->
mainReq()->isLLSC() &&
1434 ((store_has_lower_limit && lower_load_has_store_part) ||
1435 (store_has_upper_limit && upper_load_has_store_part) ||
1436 (lower_load_has_store_part && upper_load_has_store_part))) ||
1439 (request->
mainReq()->isLLSC() &&
1440 ((store_has_lower_limit || upper_load_has_store_part) &&
1441 (store_has_upper_limit || lower_load_has_store_part))) ||
1444 (store_it->instruction()->isAtomic() &&
1445 ((store_has_lower_limit || upper_load_has_store_part) &&
1446 (store_has_upper_limit || lower_load_has_store_part)))) {
1453 int shift_amt = request->
mainReq()->getVaddr() -
1454 store_it->instruction()->effAddr;
1457 if (!load_inst->memData) {
1458 load_inst->memData =
1459 new uint8_t[request->
mainReq()->getSize()];
1461 if (store_it->isAllZeros())
1462 memset(load_inst->memData, 0,
1463 request->
mainReq()->getSize());
1465 memcpy(load_inst->memData,
1466 store_it->
data() + shift_amt,
1467 request->
mainReq()->getSize());
1470 "addr %#x\n", store_it._idx,
1471 request->
mainReq()->getVaddr());
1484 assert(!request->
mainReq()->isHTMCmd());
1485 if (load_inst->inHtmTransactionalState()) {
1486 assert (!
storeQueue[store_it._idx].completed());
1489 inHtmTransactionalState());
1491 load_inst->getHtmTransactionUid() ==
1493 getHtmTransactionUid());
1495 load_inst->getHtmTransactionUid());
1496 DPRINTF(HtmCpu,
"HTM LD (ST2LDF) "
1497 "pc=0x%lx - vaddr=0x%lx - "
1498 "paddr=0x%lx - htmUid=%u\n",
1499 load_inst->pcState().instAddr(),
1500 data_pkt->
req->hasVaddr() ?
1501 data_pkt->
req->getVaddr() : 0lu,
1503 load_inst->getHtmTransactionUid());
1533 if (store_it->completed()) {
1534 panic(
"Should not check one of these");
1552 load_inst->clearIssued();
1553 load_inst->effAddrValid(
false);
1559 "Store idx %i to load addr %#x\n",
1560 store_it._idx, request->
mainReq()->getVaddr());
1571 DPRINTF(
LSQUnit,
"Doing memory access for inst [sn:%lli] PC %s\n",
1572 load_inst->seqNum, load_inst->pcState());
1575 if (!load_inst->memData) {
1576 load_inst->memData =
new uint8_t[request->
mainReq()->getSize()];
1581 if (request->
mainReq()->isHTMCmd()) {
1585 *load_inst->memData = (uint64_t) 0x1ull;
1608 DPRINTF(
LSQUnit,
"Doing write to store idx %i, addr %#x | storeHead:%i "
1611 storeQueue[store_idx].instruction()->seqNum);
1614 unsigned size = request->
_size;
1616 bool store_no_data =
1618 storeQueue[store_idx].isAllZeros() = store_no_data;
1623 !request->
req()->isCacheMaintenance() &&
1624 !request->
req()->isAtomic())
Addr cacheLineSize() const
Get the cache line size of the system.
virtual ThreadContext * getContext(int tn)
Given a thread num get tho thread context for it.
unsigned numContexts()
Get the number of thread contexts available.
bool switchedOut() const
Determine if the CPU is switched out.
virtual void handleLockedSnoop(PacketPtr pkt, Addr cacheBlockMask)
void verify(const DynInstPtr &inst)
iterator getIterator(size_t idx)
Return an iterator to an index in the queue.
Tick clockEdge(Cycles cycles=Cycles(0)) const
Determine the tick when a cycle begins, by default the current one, but the argument also enables the...
Cycles ticksToCycles(Tick t) const
Cycles is a wrapper class for representing cycle counts, i.e.
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
void setHtmTransactionFailedInCache(const HtmCacheFailure ret_code)
Stipulates that this packet/request has returned from the cache hierarchy in a failed transaction.
void print(std::ostream &o, int verbosity=0, const std::string &prefix="") const
void dataStatic(T *p)
Set the data pointer to the following value that should not be freed.
SenderState * senderState
This packet's sender state.
HtmCacheFailure getHtmTransactionFailedInCacheRC() const
If a packet/request has returned from the cache hierarchy in a failed transaction,...
bool isHtmTransactional() const
Returns whether or not this packet/request originates in the CPU executing in transactional mode,...
uint64_t getHtmTransactionUid() const
If a packet/request originates in a CPU executing in transactional mode, i.e.
RequestPtr req
A pointer to the original request.
void setHtmTransactional(uint64_t val)
Stipulates that this packet/request originates in the CPU executing in transactional mode,...
bool isInvalidate() const
bool htmTransactionFailedInCache() const
Returns whether or not this packet/request has returned from the cache hierarchy in a failed transact...
T * data
The stored pointer.
T * get() const
Directly access the pointer itself without taking a reference.
A RequestPort is a specialisation of a Port, which implements the default protocol for the three diff...
bool sendTimingReq(PacketPtr pkt)
Attempt to send a timing request to the responder port by calling its corresponding receive function.
@ LLSC
The request is a Load locked/store conditional.
@ CACHE_BLOCK_ZERO
This is a write that is targeted and zeroing an entire cache block.
static const FlagsType STORE_NO_DATA
ThreadContext is the external interface to all thread state for anything outside of the CPU.
virtual BaseISA * getIsaPtr() const =0
virtual BaseHTMCheckpointPtr & getHtmCheckpointPtr()=0
O3CPU class, has each of the stages (fetch through commit) within it, as well as all of the time buff...
gem5::Checker< DynInstPtr > * checker
Pointer to the checker, which can dynamically verify instruction results at run time.
std::vector< ThreadState * > thread
Pointers to all of the threads in the CPU.
void activityThisCycle()
Records that there was time buffer activity this cycle.
ProbePointArg< std::pair< DynInstPtr, PacketPtr > > * ppDataAccessComplete
gem5::ThreadContext * tcBase(ThreadID tid)
Returns a pointer to a thread context.
void wakeCPU()
Wakes the CPU, rescheduling the CPU if it's not already active.
IEW handles both single threaded and SMT IEW (issue/execute/writeback).
void instToCommit(const DynInstPtr &inst)
Sends an instruction to commit through the time buffer.
void blockMemInst(const DynInstPtr &inst)
Moves memory instruction onto the list of cache blocked instructions.
void activityThisCycle()
Reports to the CPU that there is activity this cycle.
void wakeCPU()
Tells the CPU to wakeup if it has descheduled itself due to no activity.
void rescheduleMemInst(const DynInstPtr &inst)
Tells memory dependence unit that a memory instruction needs to be rescheduled.
std::string name() const
Returns the name of the IEW stage.
void checkMisprediction(const DynInstPtr &inst)
Check misprediction
bool updateLSQNextCycle
Records if the LSQ needs to be updated on the next cycle, so that IEW knows if there will be activity...
void replayMemInst(const DynInstPtr &inst)
Re-executes all rescheduled memory instructions.
void setRequest(LSQRequest *r)
const DynInstPtr & instruction() const
static constexpr size_t DataSize
Writeback event, specifically for when stores forward data to loads.
WritebackEvent(const DynInstPtr &_inst, PacketPtr pkt, LSQUnit *lsq_ptr)
Constructs a writeback event.
const char * description() const
Returns the description of this event.
void process()
Processes the writeback event.
Class that implements the actual LQ and SQ for each specific thread.
void insertStore(const DynInstPtr &store_inst)
Inserts a store instruction.
Fault write(LSQRequest *requst, uint8_t *data, ssize_t store_idx)
Executes the store at the given index.
Addr cacheBlockMask
Address Mask for a cache block (e.g.
IEW * iewStage
Pointer to the IEW stage.
bool isStoreBlocked
Whehter or not a store is blocked due to the memory system.
@ PartialAddrRangeCoverage
void takeOverFrom()
Takes over from another CPU's thread.
bool checkLoads
Should loads be checked for dependency issues.
Fault read(LSQRequest *request, ssize_t load_idx)
Executes the load at the given index.
bool storeInFlight
Whether or not a store is in flight.
CPU * cpu
Pointer to the CPU.
InstSeqNum getStoreHeadSeqNum()
Returns the sequence number of the head store instruction.
InstSeqNum getLoadHeadSeqNum()
Returns the sequence number of the head load instruction.
unsigned depCheckShift
The number of places to shift addresses in the LSQ before checking for dependency violations.
void storePostSend()
Handles completing the send of a store to memory.
RequestPort * dcachePort
Pointer to the dcache port.
InstSeqNum stallingStoreIsn
The store that causes the stall due to partial store to load forwarding.
bool isStalled()
Returns whether or not the LSQ unit is stalled.
void insertLoad(const DynInstPtr &load_inst)
Inserts a load instruction.
Fault executeStore(const DynInstPtr &inst)
Executes a store instruction.
void insert(const DynInstPtr &inst)
Inserts an instruction.
bool checkStaleTranslations() const
uint64_t getLatestHtmUid() const
void schedule(Event &ev, Tick when)
Schedule event for the cpu.
void writebackStores()
Writes back stores.
Fault checkViolations(typename LoadQueue::iterator &loadIt, const DynInstPtr &inst)
Check for ordering violations in the LSQ.
StoreQueue storeQueue
The store queue.
Fault executeLoad(const DynInstPtr &inst)
Executes a load instruction.
void commitLoad()
Commits the head load.
LSQUnit(uint32_t lqEntries, uint32_t sqEntries)
Constructs an LSQ unit.
void completeStore(typename StoreQueue::iterator store_idx)
Completes the store at the specified index.
void drainSanityCheck() const
Perform sanity checks after a drain.
void setDcachePort(RequestPort *dcache_port)
Sets the pointer to the dcache port.
unsigned int cacheLineSize()
void resetState()
Reset the LSQ state.
unsigned numFreeStoreEntries()
Returns the number of free SQ entries.
uint64_t lastRetiredHtmUid
void dumpInsts() const
Debugging function to dump instructions in the LSQ.
bool stalled
Whether or not the LSQ is stalled.
ssize_t stallingLoadIdx
The index of the above store.
LoadQueue loadQueue
The load queue.
PacketPtr retryPkt
The packet that needs to be retried.
void init(CPU *cpu_ptr, IEW *iew_ptr, const BaseO3CPUParams ¶ms, LSQ *lsq_ptr, unsigned id)
Initializes the LSQ unit with the specified number of entries.
DynInstPtr getMemDepViolator()
Returns the memory ordering violator.
DynInstPtr memDepViolator
The oldest load that caused a memory ordering violation.
void squash(const InstSeqNum &squashed_num)
Squashes all instructions younger than a specific sequence number.
std::string name() const
Returns the name of the LSQ unit.
void checkSnoop(PacketPtr pkt)
Check if an incoming invalidate hits in the lsq on a load that might have issued out of order wrt ano...
static constexpr auto MaxDataBytes
void recvRetry()
Handles doing the retry.
int storesToWB
The number of store instructions in the SQ waiting to writeback.
unsigned numFreeLoadEntries()
Returns the number of free LQ entries.
bool trySendPacket(bool isLoad, PacketPtr data_pkt)
Attempts to send a packet to the cache.
void writeback(const DynInstPtr &inst, PacketPtr pkt)
Writes back the instruction, sending it to IEW.
StoreQueue::iterator storeWBIt
The index of the first instruction that may be ready to be written back, and has not yet been written...
void writebackBlockedStore()
Try to finish a previously blocked write back attempt.
void commitLoads(InstSeqNum &youngest_inst)
Commits loads older than a specific sequence number.
gem5::o3::LSQUnit::LSQUnitStats stats
void completeDataAccess(PacketPtr pkt)
Completes the data access that has been returned from the memory system.
void startStaleTranslationFlush()
LSQ * lsq
Pointer to the LSQ.
bool needsTSO
Flag for memory model.
void commitStores(InstSeqNum &youngest_inst)
Commits stores older than a specific sequence number.
ThreadID lsqID
The LSQUnit thread id.
bool recvTimingResp(PacketPtr pkt)
Handles writing back and completing the load or store that has returned from memory.
Memory operation metadata.
virtual bool recvTimingResp(PacketPtr pkt)=0
virtual void buildPackets()=0
virtual RequestPtr mainReq()
virtual bool isCacheBlockHit(Addr blockAddr, Addr cacheBlockMask)=0
Test if the request accesses a particular cache line.
void discard()
The request is discarded (e.g.
PacketPtr packet(int idx=0)
uint32_t _numOutstandingPackets
void packetNotSent()
Update the status to reflect that a packet was not sent.
bool isReleased()
Test if the LSQRequest has been released, i.e.
bool isAnyOutstandingRequest()
Test if there is any in-flight translation or mem access request.
virtual void sendPacketToCache()=0
void packetSent()
Update the status to reflect that a packet was sent.
bool needWBToRegister() const
RequestPtr req(int idx=0)
virtual PacketPtr mainPacket()
const DynInstPtr & instruction()
bool cacheBlocked() const
Is D-cache blocked?
void cachePortBusy(bool is_load)
Another store port is in use.
bool cachePortAvailable(bool is_load) const
Is any store port available to use?
Derived & flags(Flags _flags)
Set the flags and marks this stat to print at the end of simulation.
void sample(const U &v, int n=1)
Add a value to the distribtion n times.
Distribution & init(Counter min, Counter max, Counter bkt)
Set the parameters of this distribution.
#define ADD_STAT(n,...)
Convenience macro to add a stat to a statistics group.
void pop_front(size_t num_elem=1)
Circularly increase the head pointer.
bool empty() const
Is the queue empty?
void pop_back()
Circularly decrease the tail pointer.
void advance_tail()
Increases the tail by one.
bool full() const
Is the queue full? A queue is full if the head is the 0^{th} element and the tail is the (size-1)^{th...
iterator begin()
Iterators.
void schedule(Event &event, Tick when)
#define panic(...)
This implements a cprintf based panic() function.
void addStatGroup(const char *name, Group *block)
Add a stat block as a child of this block.
static constexpr int MaxThreads
const FlagsType nozero
Don't print if this is zero.
Copyright (c) 2024 - Pranith Kumar Copyright (c) 2020 Inria All rights reserved.
std::shared_ptr< FaultBase > Fault
void cprintf(const char *format, const Args &...args)
Tick curTick()
The universal simulation clock.
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
std::string htmFailureToStr(HtmFailureFaultCause cause)
Convert enum into string to be used for debug purposes.
uint64_t Tick
Tick count type.
std::string csprintf(const char *format, const Args &...args)
constexpr decltype(nullptr) NoFault
Declaration of the Packet class.
Declaration of a request, the overall memory request consisting of the parts of the request that are ...
statistics::Scalar blockedByCache
Number of times the LSQ is blocked due to the cache.
statistics::Scalar forwLoads
Total number of loads forwaded from LSQ stores.
LSQUnitStats(statistics::Group *parent)
statistics::Scalar ignoredResponses
Total number of responses from the memory system that are ignored due to the instruction already bein...
statistics::Distribution loadToUse
Distribution of cycle latency between the first time a load is issued and its completion.
statistics::Scalar rescheduledLoads
Number of loads that were rescheduled.
statistics::Scalar squashedStores
Total number of squashed stores.
statistics::Scalar squashedLoads
Total number of squashed loads.
statistics::Scalar memOrderViolation
Tota number of memory ordering violations.