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"
82 params.smtLSQThreshold)),
84 params.smtLSQThreshold)),
95 if (
lsqPolicy == SMTQueuePolicy::Dynamic) {
96 DPRINTF(
LSQ,
"LSQ sharing policy set to Dynamic\n");
97 }
else if (
lsqPolicy == SMTQueuePolicy::Partitioned) {
99 "%i entries per LQ | %i entries per SQ\n",
101 }
else if (
lsqPolicy == SMTQueuePolicy::Threshold) {
103 assert(params.smtLSQThreshold > params.LQEntries);
104 assert(params.smtLSQThreshold > params.SQEntries);
106 DPRINTF(
LSQ,
"LSQ sharing policy set to Threshold: "
107 "%i entries per LQ | %i entries per SQ\n",
110 panic(
"Invalid LSQ sharing policy. Options are: Dynamic, "
111 "Partitioned, Threshold");
117 thread[tid].init(
cpu, iew_ptr, params,
this, tid);
151 DPRINTF(Drain,
"Not drained, LQ not empty.\n");
156 DPRINTF(Drain,
"Not drained, SQ not empty.\n");
170 thread[tid].takeOverFrom();
223 ThreadID tid = load_inst->threadNumber;
225 thread[tid].insertLoad(load_inst);
231 ThreadID tid = store_inst->threadNumber;
233 thread[tid].insertStore(store_inst);
241 return thread[tid].executeLoad(inst);
249 return thread[tid].executeStore(inst);
255 thread.at(tid).commitLoads(youngest_inst);
261 thread.at(tid).commitStores(youngest_inst);
270 while (threads != end) {
274 DPRINTF(Writeback,
"[tid:%i] Writing back stores. %i stores "
278 thread[tid].writebackStores();
285 thread.at(tid).squash(squashed_num);
295 while (threads != end) {
310 return thread.at(tid).getMemDepViolator();
316 return thread.at(tid).getLoadHead();
322 return thread.at(tid).getLoadHeadSeqNum();
328 return thread.at(tid).getStoreHead();
334 return thread.at(tid).getStoreHeadSeqNum();
349 return thread[tid].numHtmStarts();
357 return thread[tid].numHtmStops();
364 thread[tid].resetHtmStartsStops();
373 return thread[tid].getLatestHtmUid();
380 thread[tid].setLastRetiredHtmUid(htmUid);
406 DPRINTF(
LSQ,
"Got error packet back for address: %#X\n",
410 panic_if(!request,
"Got packet back with unknown sender state\n");
426 DPRINTF(
LSQ,
"received invalidation with response for addr:%#x\n",
430 thread[tid].checkSnoop(pkt);
451 DPRINTF(
LSQ,
"received invalidation for addr:%#x\n",
454 thread[tid].checkSnoop(pkt);
456 }
else if (pkt->
req && pkt->
req->isTlbiExtSync()) {
463 for (
auto& unit :
thread) {
464 unit.startStaleTranslationFlush();
480 while (threads != end) {
497 while (threads != end) {
514 while (threads != end) {
531 while (threads != end) {
548 while (threads != end) {
560 return thread[tid].numFreeLoadEntries();
566 return thread[tid].numFreeStoreEntries();
575 while (threads != end) {
590 if (
lsqPolicy == SMTQueuePolicy::Dynamic)
608 while (threads != end) {
624 while (threads != end) {
640 while (threads != end) {
655 if (
lsqPolicy == SMTQueuePolicy::Dynamic)
658 return thread[tid].lqFull();
667 while (threads != end) {
682 if (
lsqPolicy == SMTQueuePolicy::Dynamic)
685 return thread[tid].sqFull();
694 while (threads != end) {
707 if (
lsqPolicy == SMTQueuePolicy::Dynamic)
710 return thread[tid].isStalled();
719 while (threads != end) {
732 return thread.at(tid).hasStoresToWB();
738 return thread.at(tid).numStoresToWB();
747 while (threads != end) {
760 return thread.at(tid).willWB();
769 while (threads != end) {
779 thread.at(tid).dumpInsts();
790 [[maybe_unused]]
bool isAtomic = !isLoad && amo_op;
803 assert(!isAtomic || (isAtomic && !needs_burst));
808 if (inst->translationStarted()) {
809 request = inst->savedRequest;
812 if (htm_cmd || tlbi_cmd) {
813 assert(
addr == 0x0lu);
816 }
else if (needs_burst) {
821 size,
flags,
data, res, std::move(amo_op));
838 inst->effAddr = request->
getVaddr();
839 inst->effSize = size;
840 inst->effAddrValid(
true);
843 inst->reqToVerify = std::make_shared<Request>(*request->
req());
847 fault =
read(request, inst->lqIdx);
849 fault =
write(request,
data, inst->sqIdx);
855 inst->getFault() = fault;
857 inst->setMemAccPredicate(
false);
865 inst->traceData->setMem(
addr, size,
flags);
867 return inst->getFault();
879 if (
_inst->isSquashed()) {
882 _inst->strictlyOrdered(request->isStrictlyOrdered());
886 _inst->physEffAddr = request->getPaddr();
887 _inst->memReqFlags = request->getFlags();
888 if (request->isCondSwap()) {
890 request->setExtraData(*
_res);
907 for (
i = 0;
i < _reqs.size() && _reqs[
i] != req;
i++);
908 assert(
i < _reqs.size());
911 numInTranslationFragments--;
912 numTranslatedFragments++;
915 _mainReq->setFlags(req->getFlags());
917 if (numTranslatedFragments == _reqs.size()) {
918 if (_inst->isSquashed()) {
921 _inst->strictlyOrdered(_mainReq->isStrictlyOrdered());
922 flags.set(Flag::TranslationFinished);
923 _inst->translationCompleted(
true);
925 for (
i = 0;
i < _fault.size() && _fault[
i] ==
NoFault;
i++);
928 _inst->memReqFlags = _mainReq->getFlags();
929 if (_mainReq->isCondSwap()) {
930 assert (
i == _fault.size());
932 _mainReq->setExtraData(*_res);
934 if (
i == _fault.size()) {
936 setState(State::Request);
938 _inst->fault = _fault[
i];
939 setState(State::PartialFault);
942 _inst->fault = _fault[0];
943 setState(State::Fault);
953 assert(_reqs.size() == 0);
955 addReq(_addr, _size, _byteEnable);
957 if (_reqs.size() > 0) {
958 _reqs.back()->setReqInstSeqNum(_inst->seqNum);
959 _reqs.back()->taskId(_taskId);
960 _inst->translationStarted(
true);
961 setState(State::Translation);
962 flags.set(Flag::TranslationStarted);
964 _inst->savedRequest =
this;
965 sendFragmentToTranslation(0);
967 _inst->setMemAccPredicate(
false);
986 auto cacheLineSize = _port.cacheLineSize();
987 Addr base_addr = _addr;
990 uint32_t size_so_far = 0;
992 _mainReq = std::make_shared<Request>(base_addr,
993 _size, _flags, _inst->requestorId(),
994 _inst->pcState().instAddr(), _inst->contextId());
995 _mainReq->setByteEnable(_byteEnable);
1001 _mainReq->setPaddr(0);
1004 auto it_start = _byteEnable.begin();
1005 auto it_end = _byteEnable.begin() + (next_addr - base_addr);
1006 addReq(base_addr, next_addr - base_addr,
1008 size_so_far = next_addr - base_addr;
1011 base_addr = next_addr;
1012 while (base_addr != final_addr) {
1013 auto it_start = _byteEnable.begin() + size_so_far;
1014 auto it_end = _byteEnable.begin() + size_so_far + cacheLineSize;
1015 addReq(base_addr, cacheLineSize,
1017 size_so_far += cacheLineSize;
1018 base_addr += cacheLineSize;
1022 if (size_so_far < _size) {
1023 auto it_start = _byteEnable.begin() + size_so_far;
1024 auto it_end = _byteEnable.end();
1025 addReq(base_addr, _size - size_so_far,
1029 if (_reqs.size() > 0) {
1031 for (
auto&
r: _reqs) {
1032 r->setReqInstSeqNum(_inst->seqNum);
1036 _inst->translationStarted(
true);
1037 setState(State::Translation);
1038 flags.set(Flag::TranslationStarted);
1039 _inst->savedRequest =
this;
1040 numInTranslationFragments = 0;
1041 numTranslatedFragments = 0;
1042 _fault.resize(_reqs.size());
1044 for (uint32_t
i = 0;
i < _reqs.size();
i++) {
1045 sendFragmentToTranslation(
i);
1048 _inst->setMemAccPredicate(
false);
1054 _state(
State::NotIssued),
1055 _port(*port), _inst(inst), _data(nullptr),
1056 _res(nullptr), _addr(0), _size(0), _flags(0),
1057 _numOutstandingPackets(0), _amo_op(nullptr)
1061 _inst->isStoreConditional() ||
_inst->isAtomic() ||
1071 bool stale_translation)
1072 : _state(
State::NotIssued),
1073 numTranslatedFragments(0),
1074 numInTranslationFragments(0),
1075 _port(*port), _inst(inst), _data(
data),
1076 _res(res), _addr(
addr), _size(size),
1078 _numOutstandingPackets(0),
1079 _amo_op(
std::move(amo_op)),
1080 _hasStaleTranslation(stale_translation)
1084 _inst->isStoreConditional() ||
_inst->isAtomic() ||
1094 _port.loadQueue[_inst->lqIdx].setRequest(
this);
1098 _port.storeQueue[_inst->sqIdx].setRequest(
this);
1109 auto req = std::make_shared<Request>(
1110 addr, size, _flags, _inst->requestorId(),
1111 _inst->pcState().instAddr(), _inst->contextId(),
1112 std::move(_amo_op));
1113 req->setByteEnable(byte_enable);
1117 req->setLocalAccessor(
1120 if ((req->isHTMStart() || req->isHTMCommit())) {
1121 auto& inst = this->instruction();
1122 assert(inst->inHtmTransactionalState());
1123 pkt->setHtmTransactional(
1124 inst->getHtmTransactionUid());
1131 _reqs.push_back(req);
1137 assert(!isAnyOutstandingRequest());
1138 _inst->savedRequest =
nullptr;
1140 for (
auto r: _packets)
1147 return _inst->contextId();
1153 numInTranslationFragments++;
1154 _port.getMMUPtr()->translateTiming(req(
i), _inst->thread->getTC(),
1163 if ((!
flags.isSet(Flag::Complete)) &&
1164 (!
flags.isSet(Flag::Discarded)) &&
1165 (
flags.isSet(Flag::TranslationStarted))) {
1166 _hasStaleTranslation =
true;
1169 DPRINTF(
LSQ,
"SingleDataRequest %d 0x%08x isBlocking:%d\n",
1170 (
int)_state, (uint32_t)
flags, _hasStaleTranslation);
1178 if ((!
flags.isSet(Flag::Complete)) &&
1179 (!
flags.isSet(Flag::Discarded)) &&
1180 (
flags.isSet(Flag::TranslationStarted))) {
1181 _hasStaleTranslation =
true;
1184 DPRINTF(
LSQ,
"SplitDataRequest %d 0x%08x isBlocking:%d\n",
1185 (
int)_state, (uint32_t)
flags, _hasStaleTranslation);
1191 assert(_numOutstandingPackets == 1);
1192 flags.set(Flag::Complete);
1193 assert(pkt == _packets.front());
1194 _port.completeDataAccess(pkt);
1195 _hasStaleTranslation =
false;
1202 uint32_t pktIdx = 0;
1203 while (pktIdx < _packets.size() && pkt != _packets[pktIdx])
1205 assert(pktIdx < _packets.size());
1206 numReceivedPackets++;
1207 if (numReceivedPackets == _packets.size()) {
1208 flags.set(Flag::Complete);
1218 _port.completeDataAccess(resp);
1221 _hasStaleTranslation =
false;
1229 if (_packets.size() == 0) {
1235 _packets.back()->senderState =
this;
1240 if (_inst->inHtmTransactionalState()) {
1241 _packets.back()->setHtmTransactional(
1242 _inst->getHtmTransactionUid());
1245 "HTM %s pc=0x%lx - vaddr=0x%lx - paddr=0x%lx - htmUid=%u\n",
1246 isLoad() ?
"LD" :
"ST",
1247 _inst->pcState().instAddr(),
1248 _packets.back()->req->hasVaddr() ?
1249 _packets.back()->req->getVaddr() : 0lu,
1250 _packets.back()->getAddr(),
1251 _inst->getHtmTransactionUid());
1254 assert(_packets.size() == 1);
1261 Addr base_address = _addr;
1263 if (_packets.size() == 0) {
1267 _mainPacket->dataStatic(_inst->memData);
1272 if (_inst->inHtmTransactionalState()) {
1273 _mainPacket->setHtmTransactional(
1274 _inst->getHtmTransactionUid());
1276 "HTM LD.0 pc=0x%lx-vaddr=0x%lx-paddr=0x%lx-htmUid=%u\n",
1277 _inst->pcState().instAddr(),
1278 _mainPacket->req->hasVaddr() ?
1279 _mainPacket->req->getVaddr() : 0lu,
1280 _mainPacket->getAddr(),
1281 _inst->getHtmTransactionUid());
1284 for (
int i = 0;
i < _reqs.size() && _fault[
i] ==
NoFault;
i++) {
1288 ptrdiff_t
offset = req->getVaddr() - base_address;
1292 uint8_t* req_data =
new uint8_t[req->getSize()];
1293 std::memcpy(req_data,
1299 _packets.push_back(pkt);
1304 if (_inst->inHtmTransactionalState()) {
1305 _packets.back()->setHtmTransactional(
1306 _inst->getHtmTransactionUid());
1308 "HTM %s.%d pc=0x%lx-vaddr=0x%lx-paddr=0x%lx-htmUid=%u\n",
1309 isLoad() ?
"LD" :
"ST",
1311 _inst->pcState().instAddr(),
1312 _packets.back()->req->hasVaddr() ?
1313 _packets.back()->req->getVaddr() : 0lu,
1314 _packets.back()->getAddr(),
1315 _inst->getHtmTransactionUid());
1319 assert(_packets.size() > 0);
1325 assert(_numOutstandingPackets == 0);
1326 if (lsqUnit()->trySendPacket(isLoad(), _packets.at(0)))
1327 _numOutstandingPackets = 1;
1334 while (numReceivedPackets + _numOutstandingPackets < _packets.size() &&
1335 lsqUnit()->trySendPacket(isLoad(),
1336 _packets.at(numReceivedPackets + _numOutstandingPackets))) {
1337 _numOutstandingPackets++;
1345 return pkt->
req->localAccessor(
thread, pkt);
1355 for (
auto r: _reqs) {
1392 bool is_hit =
false;
1393 for (
auto &
r: _reqs) {
1403 if (
r->hasPaddr() && (
r->getPaddr() & blockMask) == blockAddr) {
1414 return lsq->recvTimingResp(pkt);
1425 lsq->recvTimingSnoopReq(pkt);
1431 lsq->recvReqRetry();
1439 nullptr, nullptr, nullptr)
1451 assert(_reqs.size() == 0);
1453 addReq(_addr, _size, _byteEnable);
1455 if (_reqs.size() > 0) {
1456 _reqs.back()->setReqInstSeqNum(_inst->seqNum);
1457 _reqs.back()->taskId(_taskId);
1458 _reqs.back()->setPaddr(_addr);
1459 _reqs.back()->setInstCount(_inst->getCpuPtr()->totalInsts());
1461 _inst->strictlyOrdered(_reqs.back()->isStrictlyOrdered());
1463 _inst->physEffAddr = _reqs.back()->getPaddr();
1464 _inst->memReqFlags = _reqs.back()->getFlags();
1465 _inst->savedRequest =
this;
1467 flags.set(Flag::TranslationStarted);
1468 flags.set(Flag::TranslationFinished);
1470 _inst->translationStarted(
true);
1471 _inst->translationCompleted(
true);
1473 setState(State::Request);
1475 panic(
"unexpected behaviour in initiateTranslation()");
1484 _hasStaleTranslation =
false;
1492 panic(
"unexpected behaviour - finish()");
1500 DPRINTF(
LSQ,
"Checking pending TLBI sync\n");
1502 for (
const auto& unit :
thread) {
1503 if (unit.checkStaleTranslations())
1506 DPRINTF(
LSQ,
"No threads have blocking TLBI sync\n");
1518 panic(
"Couldn't send TLBI_EXT_SYNC_COMP message");
1528 assert(request->
req()->contextId() == request->
contextId());
1531 return thread.at(tid).read(request, load_idx);
1539 return thread.at(tid).write(request,
data, store_idx);
RequestorID dataRequestorId() const
Reads this CPU's unique data requestor ID.
Addr cacheLineSize() const
Get the cache line size of the system.
AddressMonitor * getCpuAddrMonitor(ThreadID tid)
uint32_t taskId() const
Get cpu task id.
ThreadID numThreads
Number of threads we're actually simulating (<= SMT_MAX_THREADS).
ThreadID contextToThread(ContextID cid)
Convert ContextID to threadID.
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.
bool isInvalidate() const
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.
@ 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 RequestPtr createMemManagement(Flags flags, RequestorID id)
Factory method for creating memory management requests, with unspecified addr and size.
static const FlagsType TLBI_CMD
static const FlagsType HTM_CMD
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...
gem5::Checker< DynInstPtr > * checker
Pointer to the checker, which can dynamically verify instruction results at run time.
virtual void wakeup(ThreadID tid) override
Fetch class handles both single threaded and SMT fetch.
IEW handles both single threaded and SMT IEW (issue/execute/writeback).
std::string name() const
Returns the name of the IEW stage.
void cacheUnblocked()
Notifies that the cache has become unblocked.
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.
virtual void recvReqRetry()
Handles doing a retry of the previous send.
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.
std::vector< bool > _byteEnable
LSQRequest(LSQUnit *port, const DynInstPtr &inst, bool isLoad)
virtual ~LSQRequest()
Destructor.
void install()
Install the request in the LQ/SQ.
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...
void sendFragmentToTranslation(int i)
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
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()
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()
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?
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.
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.
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.
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.
std::unique_ptr< AtomicOpFunctor > AtomicOpFunctorPtr
void set(Type mask)
Set all flag's bits matching the given mask.
#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
const FlagsType total
Print the total.
Copyright (c) 2024 - Pranith Kumar Copyright (c) 2020 Inria All rights reserved.
std::shared_ptr< FaultBase > Fault
int16_t ThreadID
Thread index/ID type.
std::shared_ptr< Request > RequestPtr
const ThreadID InvalidThreadID
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...
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.
bool doMonitor(PacketPtr pkt)
const std::string & name()