54#include "debug/Drain.hh"
55#include "debug/Fetch.hh"
56#include "debug/HtmCpu.hh"
57#include "debug/LSQ.hh"
58#include "debug/Writeback.hh"
59#include "params/BaseO3CPU.hh"
75 "Number of received responses"),
77 "Number of received response bytes"),
81 "Average bandwidth of received responses"),
85 "Average packet size per received response"),
89 "Average rate of received responses per cycle"),
93 "Average retry rate per received response"),
95 "Number of retry responses sent")
121 params.smtLSQThreshold)),
123 params.smtLSQThreshold)),
135 assert(numThreads > 0 && numThreads <=
MaxThreads);
142 if (lsqPolicy == SMTQueuePolicy::Dynamic) {
143 DPRINTF(
LSQ,
"LSQ sharing policy set to Dynamic\n");
144 }
else if (lsqPolicy == SMTQueuePolicy::Partitioned) {
145 DPRINTF(Fetch,
"LSQ sharing policy set to Partitioned: "
146 "%i entries per LQ | %i entries per SQ\n",
147 maxLQEntries,maxSQEntries);
148 }
else if (lsqPolicy == SMTQueuePolicy::Threshold) {
150 assert(params.smtLSQThreshold > params.LQEntries);
151 assert(params.smtLSQThreshold > params.SQEntries);
153 DPRINTF(LSQ,
"LSQ sharing policy set to Threshold: "
154 "%i entries per LQ | %i entries per SQ\n",
155 maxLQEntries,maxSQEntries);
157 panic(
"Invalid LSQ sharing policy. Options are: Dynamic, "
158 "Partitioned, Threshold");
161 thread.reserve(numThreads);
162 for (
ThreadID tid = 0; tid < numThreads; tid++) {
163 thread.emplace_back(maxLQEntries, maxSQEntries);
164 thread[tid].init(cpu, iew_ptr, params,
this, tid);
165 thread[tid].setDcachePort(&dcachePort);
198 DPRINTF(Drain,
"Not drained, LQ not empty.\n");
203 DPRINTF(Drain,
"Not drained, SQ not empty.\n");
217 thread[tid].takeOverFrom();
270 ThreadID tid = load_inst->threadNumber;
272 thread[tid].insertLoad(load_inst);
278 ThreadID tid = store_inst->threadNumber;
280 thread[tid].insertStore(store_inst);
288 return thread[tid].executeLoad(inst);
296 return thread[tid].executeStore(inst);
302 thread.at(tid).commitLoads(youngest_inst);
308 thread.at(tid).commitStores(youngest_inst);
316 DPRINTF(Writeback,
"[tid:%i] Writing back stores. %i stores "
320 thread[tid].writebackStores();
327 thread.at(tid).squash(squashed_num);
347 return thread.at(tid).getMemDepViolator();
353 return thread.at(tid).getLoadHead();
359 return thread.at(tid).getLoadHeadSeqNum();
365 return thread.at(tid).getStoreHead();
371 return thread.at(tid).getStoreHeadSeqNum();
386 return thread[tid].numHtmStarts();
394 return thread[tid].numHtmStops();
401 thread[tid].resetHtmStartsStops();
410 return thread[tid].getLatestHtmUid();
417 thread[tid].setLastRetiredHtmUid(htmUid);
436 .completeDataAccess(pkt);
449 DPRINTF(
LSQ,
"Got error packet back for address: %#X\n",
453 panic_if(!request,
"Got packet back with unknown sender state\n");
469 DPRINTF(
LSQ,
"received invalidation with response for addr:%#x\n",
473 thread[tid].checkSnoop(pkt);
494 DPRINTF(
LSQ,
"received invalidation for addr:%#x\n",
497 thread[tid].checkSnoop(pkt);
499 }
else if (pkt->
req && pkt->
req->isTlbiExtSync()) {
506 for (
auto& unit :
thread) {
507 unit.startStaleTranslationFlush();
578 return thread[tid].numFreeLoadEntries();
584 return thread[tid].numFreeStoreEntries();
603 if (
lsqPolicy == SMTQueuePolicy::Dynamic)
653 if (
lsqPolicy == SMTQueuePolicy::Dynamic)
656 return thread[tid].lqFull();
675 if (
lsqPolicy == SMTQueuePolicy::Dynamic)
678 return thread[tid].sqFull();
695 if (
lsqPolicy == SMTQueuePolicy::Dynamic)
698 return thread[tid].isStalled();
715 return thread.at(tid).hasStoresToWB();
721 return thread.at(tid).numStoresToWB();
738 return thread.at(tid).willWB();
752 thread.at(tid).dumpInsts();
763 [[maybe_unused]]
bool isAtomic = !isLoad && amo_op;
765 ThreadID tid =
cpu->contextToThread(inst->contextId());
766 auto cacheLineSize =
cpu->cacheLineSize();
776 assert(!isAtomic || (isAtomic && !needs_burst));
781 if (inst->translationStarted()) {
782 request = inst->savedRequest;
785 if (htm_cmd || tlbi_cmd) {
786 assert(
addr == 0x0lu);
789 }
else if (needs_burst) {
791 size, flags,
data, res);
794 size, flags,
data, res, std::move(amo_op));
811 inst->effAddr = request->
getVaddr();
812 inst->effSize = size;
813 inst->effAddrValid(
true);
816 inst->reqToVerify = std::make_shared<Request>(*request->
req());
820 fault =
read(request, inst->lqIdx);
822 fault =
write(request,
data, inst->sqIdx);
828 inst->getFault() = fault;
830 inst->setMemAccPredicate(
false);
838 inst->traceData->setMem(
addr, size, flags);
840 return inst->getFault();
852 if (
_inst->isSquashed()) {
855 _inst->strictlyOrdered(request->isStrictlyOrdered());
859 _inst->physEffAddr = request->getPaddr();
860 _inst->memReqFlags = request->getFlags();
861 if (request->isCondSwap()) {
863 request->setExtraData(*
_res);
891 if (
_inst->isSquashed()) {
896 _inst->translationCompleted(
true);
926 assert(
_reqs.size() == 0);
930 if (
_reqs.size() > 0) {
931 _reqs.back()->setReqInstSeqNum(
_inst->seqNum);
933 _inst->translationStarted(
true);
937 _inst->savedRequest =
this;
940 _inst->setMemAccPredicate(
false);
959 auto cacheLineSize =
_port.cacheLineSize();
963 uint32_t size_so_far = 0;
965 _mainReq = std::make_shared<Request>(base_addr,
967 _inst->pcState().instAddr(),
_inst->contextId());
978 auto it_end =
_byteEnable.begin() + (next_addr - base_addr);
979 addReq(base_addr, next_addr - base_addr,
981 size_so_far = next_addr - base_addr;
984 base_addr = next_addr;
985 while (base_addr != final_addr) {
987 auto it_end =
_byteEnable.begin() + size_so_far + cacheLineSize;
988 addReq(base_addr, cacheLineSize,
990 size_so_far += cacheLineSize;
991 base_addr += cacheLineSize;
995 if (size_so_far <
_size) {
1002 if (
_reqs.size() > 0) {
1005 r->setReqInstSeqNum(
_inst->seqNum);
1009 _inst->translationStarted(
true);
1012 _inst->savedRequest =
this;
1017 for (uint32_t
i = 0;
i <
_reqs.size();
i++) {
1021 _inst->setMemAccPredicate(
false);
1034 _inst->isStoreConditional() ||
_inst->isAtomic() ||
1044 bool stale_translation)
1057 _inst->isStoreConditional() ||
_inst->isAtomic() ||
1067 _port.loadQueue[
_inst->lqIdx].setRequest(
this);
1071 _port.storeQueue[
_inst->sqIdx].setRequest(
this);
1084 _inst->pcState().instAddr(),
_inst->contextId(),
1086 req->setByteEnable(byte_enable);
1090 req->setLocalAccessor(
1093 if ((
req->isHTMStart() ||
req->isHTMCommit())) {
1095 assert(inst->inHtmTransactionalState());
1097 inst->getHtmTransactionUid());
1111 _inst->savedRequest =
nullptr;
1120 return _inst->contextId();
1127 _port.getMMUPtr()->translateTiming(
req(
i),
_inst->thread->getTC(),
1142 DPRINTF(
LSQ,
"SingleDataRequest %d 0x%08x isBlocking:%d\n",
1157 DPRINTF(
LSQ,
"SplitDataRequest %d 0x%08x isBlocking:%d\n",
1167 _port.completeDataAccess(pkt);
1175 uint32_t pktIdx = 0;
1191 _port.completeDataAccess(resp);
1208 _packets.back()->senderState =
this;
1213 if (
_inst->inHtmTransactionalState()) {
1214 _packets.back()->setHtmTransactional(
1215 _inst->getHtmTransactionUid());
1218 "HTM %s pc=0x%lx - vaddr=0x%lx - paddr=0x%lx - htmUid=%u\n",
1220 _inst->pcState().instAddr(),
1222 _packets.back()->req->getVaddr() : 0lu,
1224 _inst->getHtmTransactionUid());
1245 if (
_inst->inHtmTransactionalState()) {
1247 _inst->getHtmTransactionUid());
1249 "HTM LD.0 pc=0x%lx-vaddr=0x%lx-paddr=0x%lx-htmUid=%u\n",
1250 _inst->pcState().instAddr(),
1254 _inst->getHtmTransactionUid());
1261 ptrdiff_t
offset =
req->getVaddr() - base_address;
1265 uint8_t* req_data =
new uint8_t[
req->getSize()];
1266 std::memcpy(req_data,
1277 if (
_inst->inHtmTransactionalState()) {
1278 _packets.back()->setHtmTransactional(
1279 _inst->getHtmTransactionUid());
1281 "HTM %s.%d pc=0x%lx-vaddr=0x%lx-paddr=0x%lx-htmUid=%u\n",
1284 _inst->pcState().instAddr(),
1286 _packets.back()->req->getVaddr() : 0lu,
1288 _inst->getHtmTransactionUid());
1318 return pkt->
req->localAccessor(
thread, pkt);
1365 bool is_hit =
false;
1376 if (
r->hasPaddr() && (
r->getPaddr() & blockMask) == blockAddr) {
1388 bool is_unaligned_tick =
curTick() %
cpu->clockPeriod() != 0;
1392 if (current_cycle >
lsq->recvRespLastActiveCycle) {
1393 lsq->recvRespBytes = 0;
1394 lsq->recvRespCachelines = 0;
1395 lsq->recvRespLastCachelineAddr = 0;
1398 lsq->recvRespLastActiveCycle = current_cycle;
1402 bool throttle_cycle =
false;
1405 bool is_new_cacheline = cacheline_addr !=
lsq->recvRespLastCachelineAddr;
1406 bool max_cachelines = (
lsq->recvRespCachelines + is_new_cacheline)
1407 >
lsq->recvRespMaxCachelines;
1408 int free_buf_size =
lsq->recvRespBufferSize -
lsq->recvRespBytes;
1409 bool max_bytes = pkt->
getSize() > free_buf_size;
1412 if (
lsq->recvRespPendBytes == 0 && (max_cachelines || max_bytes)) {
1415 if (max_bytes && !max_cachelines) {
1416 lsq->recvRespBytes += free_buf_size;
1417 assert(
lsq->recvRespBytes <=
lsq->recvRespBufferSize);
1419 lsq->recvRespPendBytes = pkt->
getSize() - free_buf_size;
1423 throttle_cycle =
true;
1424 DPRINTF(
LSQ,
"throttling ReadResp: max_cachelines=%d max_bytes=%d\n",
1425 max_cachelines, max_bytes);
1428 }
else if (
lsq->recvRespPendBytes > 0) {
1429 DPRINTF(
LSQ,
"recvRespPendBytes=%u\n",
lsq->recvRespPendBytes);
1432 assert(
lsq->recvRespBytes == 0 &&
lsq->recvRespCachelines == 0);
1435 throttle_cycle =
lsq->recvRespPendBytes >
lsq->recvRespBufferSize;
1438 lsq->recvRespBytes += (throttle_cycle) ?
lsq->recvRespBufferSize
1439 :
lsq->recvRespPendBytes;
1440 lsq->recvRespPendBytes -=
lsq->recvRespBytes;
1450 if (is_new_cacheline) {
1451 lsq->recvRespCachelines++;
1452 lsq->recvRespLastCachelineAddr = cacheline_addr;
1456 if (throttle_cycle) {
1457 Tick next_cycle =
cpu->cyclesToTicks(current_cycle +
Cycles(1));
1460 assert(next_cycle >
curTick());
1461 assert(!(
lsq->retryRespEvent.scheduled()));
1464 cpu->schedule(
lsq->retryRespEvent, next_cycle);
1465 DPRINTF(
LSQ,
"retryRespEvent scheduled for tick=%lu\n", next_cycle);
1470 return throttle_cycle;
1485 return lsq->recvTimingResp(pkt);
1491 for (
ThreadID tid = 0; tid <
cpu->numThreads; tid++) {
1492 if (
cpu->getCpuAddrMonitor(tid)->doMonitor(pkt)) {
1496 lsq->recvTimingSnoopReq(pkt);
1502 lsq->recvReqRetry();
1510 nullptr, nullptr, nullptr)
1522 assert(
_reqs.size() == 0);
1526 if (
_reqs.size() > 0) {
1527 _reqs.back()->setReqInstSeqNum(
_inst->seqNum);
1530 _reqs.back()->setInstCount(
_inst->getCpuPtr()->totalInsts());
1532 _inst->strictlyOrdered(
_reqs.back()->isStrictlyOrdered());
1534 _inst->physEffAddr =
_reqs.back()->getPaddr();
1535 _inst->memReqFlags =
_reqs.back()->getFlags();
1536 _inst->savedRequest =
this;
1541 _inst->translationStarted(
true);
1542 _inst->translationCompleted(
true);
1546 panic(
"unexpected behaviour in initiateTranslation()");
1563 panic(
"unexpected behaviour - finish()");
1571 DPRINTF(
LSQ,
"Checking pending TLBI sync\n");
1573 for (
const auto& unit :
thread) {
1574 if (unit.checkStaleTranslations())
1577 DPRINTF(
LSQ,
"No threads have blocking TLBI sync\n");
1583 cpu->dataRequestorId());
1589 panic(
"Couldn't send TLBI_EXT_SYNC_COMP message");
1599 assert(request->
req()->contextId() == request->
contextId());
1600 ThreadID tid =
cpu->contextToThread(request->
req()->contextId());
1602 return thread.at(tid).read(request, load_idx);
1608 ThreadID tid =
cpu->contextToThread(request->
req()->contextId());
1610 return thread.at(tid).write(request,
data, store_idx);
gem5::BaseCPU::BaseCPUStats baseStats
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....
const std::string & cmdString() const
Return the string name of the cmd field (for debugging and tracing).
static PacketPtr createWrite(const RequestPtr &req)
void dataStatic(T *p)
Set the data pointer to the following value that should not be freed.
SenderState * senderState
This packet's sender state.
T * getPtr()
get a pointer to the data ptr.
static PacketPtr createRead(const RequestPtr &req)
Constructor-like methods that return Packets based on Request objects.
RequestPtr req
A pointer to the original request.
void dataDynamic(T *p)
Set the data pointer to a value that should have delete [] called on it.
void setHtmTransactional(uint64_t val)
Stipulates that this packet/request originates in the CPU executing in transactional mode,...
MemCmd cmd
The command field of the packet.
bool isInvalidate() const
RequestPort(const std::string &name, SimObject *_owner, PortID id=InvalidPortID)
Request port.
static RequestPtr createMemManagement(Flags flags, RequestorID id)
Factory method for creating memory management requests, with unspecified addr and size.
static const FlagsType TLBI_CMD
@ TLBI_EXT_SYNC_COMP
The Request tells the interconnect that a remote TLB Sync request has completed.
@ NO_ACCESS
The request should not cause a memory access.
static const FlagsType HTM_CMD
gem5::Flags< FlagsType > Flags
ThreadContext is the external interface to all thread state for anything outside of the CPU.
O3CPU class, has each of the stages (fetch through commit) within it, as well as all of the time buff...
IEW handles both single threaded and SMT IEW (issue/execute/writeback).
Class that implements the actual LQ and SQ for each specific thread.
virtual void recvTimingSnoopReq(PacketPtr pkt)
Receive a timing snoop request from the peer.
DcachePort(LSQ *_lsq, CPU *_cpu)
Default constructor.
virtual bool recvTimingResp(PacketPtr pkt)
Timing version of receive.
gem5::o3::LSQ::DcachePort::DcachePortStats dcachePortStats
virtual void recvReqRetry()
Handles doing a retry of the previous send.
bool throttleReadResp(PacketPtr pkt)
Applies throttling in recvTimingResp for incoming load responses.
Memory operation metadata.
@ IsAtomic
True if this is an atomic request.
@ TranslationFinished
True if there are un-replied outbound translations.
@ WriteBackToRegister
True if this request needs to writeBack to register.
@ TranslationStarted
True if any translation has been sent to TLB.
@ Discarded
Request discarded.
std::vector< bool > _byteEnable
LSQRequest(LSQUnit *port, const DynInstPtr &inst, bool isLoad)
virtual ~LSQRequest()
Destructor.
void install()
Install the request in the LQ/SQ.
AtomicOpFunctorPtr _amo_op
ContextID contextId() const
void taskId(const uint32_t &v)
virtual void initiateTranslation()=0
void setState(const State &newState)
void addReq(Addr addr, unsigned size, const std::vector< bool > &byte_enable)
Helper function used to add a (sub)request, given its address addr, size size and byte-enable mask by...
uint32_t _numOutstandingPackets
bool _hasStaleTranslation
bool isAnyOutstandingRequest()
Test if there is any in-flight translation or mem access request.
void sendFragmentToTranslation(int i)
const Request::Flags _flags
uint32_t numTranslatedFragments
std::vector< Fault > _fault
bool isMemAccessRequired()
uint32_t numInTranslationFragments
bool squashed() const override
This function is used by the page table walker to determine if it should translate the a pending requ...
RequestPtr req(int idx=0)
std::vector< RequestPtr > _reqs
std::vector< PacketPtr > _packets
const DynInstPtr & instruction()
bool isTranslationComplete()
Addr getVaddr(int idx=0) const
virtual Cycles handleLocalAccess(gem5::ThreadContext *thread, PacketPtr pkt)
Memory mapped IPR accesses.
virtual void finish(const Fault &fault, const RequestPtr &req, gem5::ThreadContext *tc, BaseMMU::Mode mode)
virtual void initiateTranslation()
SingleDataRequest(LSQUnit *port, const DynInstPtr &inst, bool isLoad, const Addr &addr, const uint32_t &size, const Request::Flags &flags_, PacketDataPtr data=nullptr, uint64_t *res=nullptr, AtomicOpFunctorPtr amo_op=nullptr)
virtual bool recvTimingResp(PacketPtr pkt)
virtual void buildPackets()
virtual void markAsStaleTranslation()
virtual void sendPacketToCache()
virtual bool isCacheBlockHit(Addr blockAddr, Addr cacheBlockMask)
Test if the request accesses a particular cache line.
virtual bool recvTimingResp(PacketPtr pkt)
virtual bool isCacheBlockHit(Addr blockAddr, Addr cacheBlockMask)
Caches may probe into the load-store queue to enforce memory ordering guarantees.
virtual void initiateTranslation()
virtual void markAsStaleTranslation()
virtual void finish(const Fault &fault, const RequestPtr &req, gem5::ThreadContext *tc, BaseMMU::Mode mode)
virtual PacketPtr mainPacket()
virtual Cycles handleLocalAccess(gem5::ThreadContext *thread, PacketPtr pkt)
Memory mapped IPR accesses.
virtual void sendPacketToCache()
virtual RequestPtr mainReq()
virtual void buildPackets()
uint32_t numReceivedPackets
virtual void initiateTranslation()
virtual void markAsStaleTranslation()
virtual void finish(const Fault &fault, const RequestPtr &req, gem5::ThreadContext *tc, BaseMMU::Mode mode)
UnsquashableDirectRequest(LSQUnit *port, const DynInstPtr &inst, const Request::Flags &flags_)
unsigned SQEntries
Total Size of SQ Entries.
bool isDrained() const
Has the LSQ drained?
EventFunctionWrapper retryRespEvent
int cacheLoadPorts
The number of cache ports available each cycle (loads only).
int usedStorePorts
The number of used cache ports in this cycle by stores.
int numHtmStarts(ThreadID tid) const
std::string name() const
Returns the name of the LSQ.
void commitStores(InstSeqNum &youngest_inst, ThreadID tid)
Commits stores up until the given sequence number for a specific thread.
Addr staleTranslationWaitTxnId
The ID if the transaction that made translations stale.
bool recvTimingResp(PacketPtr pkt)
Handles writing back and completing the load or store that has returned from memory.
void checkStaleTranslations()
Checks if queues have any marked operations left, and sends the appropriate Sync Completion message i...
int getLoadHead(ThreadID tid)
Returns the head index of the load queue for a specific thread.
void squash(const InstSeqNum &squashed_num, ThreadID tid)
Squash instructions from a thread until the specified sequence number.
bool sqEmpty() const
Returns if all of the SQs are empty.
void completeDataAccess(PacketPtr pkt)
Fault pushRequest(const DynInstPtr &inst, bool isLoad, uint8_t *data, unsigned int size, Addr addr, Request::Flags flags, uint64_t *res, AtomicOpFunctorPtr amo_op, const std::vector< bool > &byte_enable)
unsigned numFreeLoadEntries()
Returns the number of free load entries.
ThreadID numThreads
Number of Threads.
IEW * iewStage
The IEW stage pointer.
InstSeqNum getLoadHeadSeqNum(ThreadID tid)
Returns the sequence number of the head of the load queue.
std::list< ThreadID > * activeThreads
List of Active Threads in System.
DcachePort dcachePort
Data port.
void takeOverFrom()
Takes over execution from another CPU's thread.
DynInstPtr getMemDepViolator(ThreadID tid)
Gets the instruction that caused the memory ordering violation.
static uint32_t maxLSQAllocation(SMTQueuePolicy pol, uint32_t entries, uint32_t numThreads, uint32_t SMTThreshold)
Auxiliary function to calculate per-thread max LSQ allocation limit.
void setActiveThreads(std::list< ThreadID > *at_ptr)
Sets the pointer to the list of active threads.
bool cacheBlocked() const
Is D-cache blocked?
int numLoads()
Returns the total number of loads in the load queue.
void setLastRetiredHtmUid(ThreadID tid, uint64_t htmUid)
void dumpInsts() const
Debugging function to print out all instructions.
int usedLoadPorts
The number of used cache ports in this cycle by loads.
unsigned maxLQEntries
Max LQ Size - Used to Enforce Sharing Policies.
bool isFull()
Returns if the LSQ is full (either LQ or SQ is full).
void insertStore(const DynInstPtr &store_inst)
Inserts a store into the LSQ.
void recvReqRetry()
Retry the previous send that failed.
void commitLoads(InstSeqNum &youngest_inst, ThreadID tid)
Commits loads up until the given sequence number for a specific thread.
Fault write(LSQRequest *request, uint8_t *data, ssize_t store_idx)
Executes a store operation, using the store specified at the store index.
Cycles recvRespLastActiveCycle
Addr recvRespLastCachelineAddr
uint64_t getLatestHtmUid(ThreadID tid) const
bool willWB()
Returns if the LSQ will write back to memory this cycle.
int getStoreHead(ThreadID tid)
Returns the head index of the store queue.
LSQ(CPU *cpu_ptr, IEW *iew_ptr, const BaseO3CPUParams ¶ms)
Constructs an LSQ with the given parameters.
CPU * cpu
The CPU pointer.
bool _cacheBlocked
D-cache is blocked.
void drainSanityCheck() const
Perform sanity checks after a drain.
std::vector< LSQUnit > thread
The LSQ units for individual threads.
unsigned LQEntries
Total Size of LQ Entries.
int numHtmStops(ThreadID tid) const
void cachePortBusy(bool is_load)
Another store port is in use.
const unsigned recvRespBufferSize
bool cachePortAvailable(bool is_load) const
Is any store port available to use?
InstSeqNum getStoreHeadSeqNum(ThreadID tid)
Returns the sequence number of the head of the store queue.
bool isStalled()
Returns if the LSQ is stalled due to a memory operation that must be replayed.
void writebackStores()
Attempts to write back stores until all cache ports are used or the interface becomes blocked.
bool lqFull()
Returns if any of the LQs are full.
bool waitingForStaleTranslation
If the LSQ is currently waiting for stale translations.
unsigned maxSQEntries
Max SQ Size - Used to Enforce Sharing Policies.
bool lqEmpty() const
Returns if all of the LQs are empty.
int getCount()
Returns the number of instructions in all of the queues.
bool hasStoresToWB()
Returns whether or not there are any stores to write back to memory.
Fault read(LSQRequest *request, ssize_t load_idx)
Executes a read operation, using the load specified at the load index.
Fault executeStore(const DynInstPtr &inst)
Executes a store.
void tick()
Ticks the LSQ.
void insertLoad(const DynInstPtr &load_inst)
Inserts a load into the LSQ.
bool isEmpty() const
Returns if the LSQ is empty (both LQ and SQ are empty).
int numStores()
Returns the total number of stores in the store queue.
void recvTimingSnoopReq(PacketPtr pkt)
int cacheStorePorts
The number of cache ports available each cycle (stores only).
Fault executeLoad(const DynInstPtr &inst)
Executes a load.
bool violation()
Returns whether or not there was a memory ordering violation.
void resetHtmStartsStops(ThreadID tid)
SMTQueuePolicy lsqPolicy
The LSQ policy for SMT mode.
const bool recvRespThrottling
Enable load receive response throttling in the LSQ.
int numStoresToWB(ThreadID tid)
Returns the number of stores a specific thread has to write back.
unsigned numFreeStoreEntries()
Returns the number of free store entries.
bool sqFull()
Returns if any of the SQs are full.
unsigned recvRespCachelines
const unsigned recvRespMaxCachelines
#define ADD_STAT(n,...)
Convenience macro to add a stat to a statistics group.
std::unique_ptr< AtomicOpFunctor > AtomicOpFunctorPtr
#define panic(...)
This implements a cprintf based panic() function.
#define panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
static constexpr int MaxThreads
RefCountingPtr< DynInst > DynInstPtr
const FlagsType total
Print the total.
Copyright (c) 2024 Arm Limited All rights reserved.
std::shared_ptr< FaultBase > Fault
int16_t ThreadID
Thread index/ID type.
std::shared_ptr< Request > RequestPtr
const ThreadID InvalidThreadID
Tick curTick()
The universal simulation clock.
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
bool transferNeedsBurst(Addr addr, unsigned int size, unsigned int block_size)
Returns true if the given memory access (address, size) needs to be fragmented across aligned fixed-s...
uint64_t Tick
Tick count type.
int ContextID
Globally unique thread context ID.
constexpr decltype(nullptr) NoFault
bool isAnyActiveElement(const std::vector< bool >::const_iterator &it_start, const std::vector< bool >::const_iterator &it_end)
Test if there is any active element in an enablement range.
Addr addrBlockAlign(Addr addr, Addr block_size)
Returns the address of the closest aligned fixed-size block to the given address.
Overload hash function for BasicBlockRange type.
statistics::Scalar numCycles
statistics::Scalar numRecvRespBytes
statistics::Scalar numSendRetryResp
statistics::Scalar numRecvResp
DcachePortStats(CPU *cpu)
statistics::Formula recvRespAvgRetryRate
statistics::Formula recvRespAvgSize
statistics::Formula recvRespAvgBW
statistics::Formula recvRespAvgRate
const std::string & name()