50#include "debug/Activity.hh"
51#include "debug/MinorMem.hh"
74 request = std::make_shared<Request>();
81 std::unique_ptr<PCStateBase> old_pc(thread.
pcState().
clone());
83 [[maybe_unused]]
Fault fault =
inst->translationFault;
86 inst->translationFault =
inst->staticInst->initiateAcc(&context,
nullptr);
89 "Translation fault suppressed for inst:%s\n", *
inst);
91 assert(
inst->translationFault == fault);
99 DPRINTFS(MinorMem, (&
port),
"Complete disabled mem access for inst:%s\n",
103 std::unique_ptr<PCStateBase> old_pc(thread.
pcState().
clone());
108 inst->staticInst->completeAcc(
nullptr, &context,
inst->traceData);
116 port.cpu.threads[
inst->id.threadId]->setMemAccPredicate(
false);
122 Addr req1_addr,
unsigned int req1_size,
123 Addr req2_addr,
unsigned int req2_size)
127 Addr req2_end_addr = req2_addr + req2_size;
128 Addr req1_end_addr = req1_addr + req1_size;
132 if (req1_addr >= req2_end_addr || req1_end_addr <= req2_addr)
134 else if (req1_addr <= req2_addr && req1_end_addr >= req2_end_addr)
146 request->getPaddr(), request->getSize(),
147 other_request->
request->getPaddr(), other_request->
request->getSize());
160 return inst->isInst() &&
inst->staticInst->isFullMemBarrier();
172 DPRINTFS(MinorMem, (&
port),
"Setting state from %d to %d for request:"
198 os <<
"PartialAddrRangeCoverage";
201 os <<
"FullAddrRangeCoverage";
204 os <<
"NoAddrRangeCoverage";
207 os <<
"AddrRangeCoverage-" <<
static_cast<int>(coverage);
221 os <<
"InTranslation";
230 os <<
"RequestIssuing";
233 os <<
"StoreToStoreBuffer";
236 os <<
"StoreInStoreBuffer";
239 os <<
"StoreBufferIssuing";
242 os <<
"RequestNeedsRetry";
245 os <<
"StoreBufferNeedsRetry";
251 os <<
"LSQRequestState-" <<
static_cast<int>(
state);
260 bool is_last_barrier =
263 DPRINTF(MinorMem,
"Moving %s barrier out of store buffer inst: %s\n",
264 (is_last_barrier ?
"last" :
"a"), *inst);
274 port.numAccessesInDTLB--;
276 DPRINTFS(MinorMem, (&
port),
"Received translation response for"
278 fault_ !=
NoFault ? fault_->name() :
"");
281 inst->translationFault = fault_;
294 port.tryToSendToTransfers(
this);
306 const auto &byte_enable =
request->getByteEnable();
308 port.numAccessesInDTLB++;
312 DPRINTFS(MinorMem, (&
port),
"Submitting DTLB request\n");
337 port.numAccessesInDTLB--;
339 [[maybe_unused]]
unsigned int expected_fragment_index =
345 DPRINTFS(MinorMem, (&
port),
"Received translation response for fragment"
346 " %d of request: %s delayed:%d %s\n", expected_fragment_index,
348 fault_ !=
NoFault ? fault_->name() :
"");
358 inst->translationFault = fault_;
360 DPRINTFS(MinorMem, (&
port),
"Faulting translation for fragment:"
361 " %d of request: %s\n",
362 expected_fragment_index, *
inst);
366 if (expected_fragment_index == 0) {
380 port.tryToSendToTransfers(
this);
384 port.tryToSendToTransfers(
this);
394 LSQRequest(port_, inst_, isLoad_, data_, res_),
398 numInTranslationFragments(0),
399 numTranslatedFragments(0),
400 numIssuedFragments(0),
401 numRetiredFragments(0),
422 unsigned int whole_size =
request->getSize();
423 unsigned int line_width =
port.lineWidth;
425 unsigned int fragment_size;
442 unsigned int first_fragment_offset =
444 unsigned int last_fragment_size =
446 unsigned int first_fragment_size =
447 line_width - first_fragment_offset;
449 unsigned int middle_fragments_total_size =
450 whole_size - (first_fragment_size + last_fragment_size);
454 unsigned int middle_fragment_count =
455 middle_fragments_total_size / line_width;
458 (last_fragment_size == 0 ? 0 : 1);
460 DPRINTFS(MinorMem, (&
port),
"Dividing transfer into %d fragmentRequests."
461 " First fragment size: %d Last fragment size: %d\n",
463 (last_fragment_size == 0 ? line_width : last_fragment_size));
465 assert(((middle_fragment_count * line_width) +
466 first_fragment_size + last_fragment_size) == whole_size);
468 fragment_addr = base_addr;
469 fragment_size = first_fragment_size;
472 Addr end_addr = base_addr + whole_size;
474 auto& byte_enable =
request->getByteEnable();
475 unsigned int num_disabled_fragments = 0;
477 for (
unsigned int fragment_index = 0; fragment_index <
numFragments;
480 [[maybe_unused]]
bool is_last_fragment =
false;
482 if (fragment_addr == base_addr) {
484 fragment_size = first_fragment_size;
486 if ((fragment_addr + line_width) > end_addr) {
488 fragment_size = end_addr - fragment_addr;
489 is_last_fragment =
true;
492 fragment_size = line_width;
496 RequestPtr fragment = std::make_shared<Request>();
497 bool disabled_fragment =
false;
499 fragment->setContext(
request->contextId());
501 auto it_start = byte_enable.begin() +
502 (fragment_addr - base_addr);
503 auto it_end = byte_enable.begin() +
504 (fragment_addr - base_addr) + fragment_size;
507 fragment_addr, fragment_size,
request->getFlags(),
512 disabled_fragment =
true;
515 if (!disabled_fragment) {
516 DPRINTFS(MinorMem, (&
port),
"Generating fragment addr: 0x%x"
517 " size: %d (whole request addr: 0x%x size: %d) %s\n",
518 fragment_addr, fragment_size, base_addr, whole_size,
519 (is_last_fragment ?
"last fragment" :
""));
523 num_disabled_fragments++;
526 fragment_addr += fragment_size;
540 for (
unsigned int fragment_index = 0;
546 DPRINTFS(MinorMem, (&
port),
"Making packet %d for request: %s"
548 fragment_index, *
inst,
549 (fragment->hasPaddr() ?
"has paddr" :
"no paddr"),
550 (fragment->hasPaddr() ? fragment->getPaddr() : 0));
552 Addr fragment_addr = fragment->getVaddr();
553 unsigned int fragment_size = fragment->getSize();
555 uint8_t *request_data = NULL;
560 request_data =
new uint8_t[fragment_size];
561 std::memcpy(request_data,
data + (fragment_addr - base_addr),
565 assert(fragment->hasPaddr());
572 request->setFlags(fragment->getFlags());
629 DPRINTFS(MinorMem, (&
port),
"Retiring fragment addr: 0x%x size: %d"
630 " offset: 0x%x (retired fragment num: %d)\n",
631 response->
req->getVaddr(), response->
req->getSize(),
632 request->getVaddr() - response->
req->getVaddr(),
640 DPRINTFS(MinorMem, (&
port),
"Skipping this fragment\n");
641 }
else if (response->
isError()) {
643 DPRINTFS(MinorMem, (&
port),
"Fragment has an error, skipping\n");
645 packet->copyError(response);
660 response->
req->getSize());
666 DPRINTFS(MinorMem, (&
port),
"Completed skipped burst\n");
668 if (
packet->needsResponse())
678 DPRINTFS(MinorMem, (&
port),
"Retired packet isRead: %d isWrite: %d"
679 " needsResponse: %d packetSize: %s requestSize: %s responseSize:"
708 DPRINTFS(MinorMem, (&
port),
"Submitting DTLB request for fragment: %d\n",
711 port.numAccessesInDTLB++;
729 auto found = std::find(
slots.begin(),
slots.end(), request);
731 if (found !=
slots.end()) {
732 DPRINTF(MinorMem,
"Deleting request: %s %s %s from StoreBuffer\n",
733 request, *found, *(request->
inst));
744 warn(
"%s: store buffer insertion without space to insert from"
745 " inst: %s\n",
name(), *(request->
inst));
748 DPRINTF(MinorMem,
"Pushing store: %s into store buffer\n", request);
755 slots.push_back(request);
764 unsigned int &found_slot)
766 unsigned int slot_index =
slots.size() - 1;
779 slot->
inst->id.threadId == request->
inst->id.threadId &&
780 !slot->
packet->
req->isCacheMaintenance()) {
784 DPRINTF(MinorMem,
"Forwarding: slot: %d result: %s thisAddr:"
785 " 0x%x thisSize: %d slotAddr: 0x%x slotSize: %d\n",
786 slot_index, coverage,
790 found_slot = slot_index;
805 unsigned int slot_number)
807 assert(slot_number <
slots.size());
818 Addr addr_offset = load_addr - store_addr;
820 unsigned int load_size = load->
request->getSize();
822 DPRINTF(MinorMem,
"Forwarding %d bytes for addr: 0x%x from store buffer"
823 " slot: %d addr: 0x%x addressOffset: 0x%x\n",
824 load_size, load_addr, slot_number,
825 store_addr, addr_offset);
828 void *store_packet_data = store->
packet->
getPtr<uint8_t>() + addr_offset;
830 std::memcpy(load_packet_data, store_packet_data, load_size);
845 DPRINTF(MinorMem,
"StoreBuffer step numUnissuedAccesses: %d\n",
850 while (!
slots.empty() &&
851 slots.front()->isComplete() &&
slots.front()->isBarrier())
855 DPRINTF(MinorMem,
"Clearing barrier for inst: %s\n",
859 lsq.clearMemBarrier(barrier->
inst);
867 unsigned int issue_count = 0;
878 lsq.canSendToMemorySystem() &&
883 DPRINTF(MinorMem,
"Considering request: %s, sentAllPackets: %d"
894 DPRINTF(MinorMem,
"Trying to send request: %s to memory"
895 " system\n", *(request->
inst));
897 if (
lsq.tryToSend(request)) {
918 if (!inst->inStoreBuffer) {
932 unsigned int size =
slots.size();
934 std::ostringstream
os;
962 DPRINTF(MinorMem,
"Request needs retry, not issuing to"
963 " memory until retry arrives\n");
968 DPRINTF(MinorMem,
"Request still in translation, not issuing to"
979 DPRINTF(MinorMem,
"Request not at front of requests queue, can't"
980 " issue to memory\n");
984 if (
transfers.unreservedRemainingSpace() == 0) {
985 DPRINTF(MinorMem,
"No space to insert request into transfers"
991 DPRINTF(MinorMem,
"Passing a %s transfer on to transfers"
992 " queue\n", (request->
isComplete() ?
"completed" :
"failed"));
1003 DPRINTF(MinorMem,
"Request's inst. is from the wrong stream,"
1004 " waiting for responses before aborting request\n");
1006 DPRINTF(MinorMem,
"Request's inst. is from the wrong stream,"
1007 " aborting request\n");
1016 if (request->
inst->staticInst->isPrefetch()) {
1017 DPRINTF(MinorMem,
"Not signalling fault for faulting prefetch\n");
1019 DPRINTF(MinorMem,
"Moving faulting request into the transfers"
1027 bool is_load = request->
isLoad;
1028 bool is_llsc = request->
request->isLLSC();
1029 bool is_release = request->
request->isRelease();
1030 bool is_swap = request->
request->isSwap();
1031 bool is_atomic = request->
request->isAtomic();
1032 bool bufferable = !(request->
request->isStrictlyOrdered() ||
1033 is_llsc || is_swap || is_atomic || is_release);
1037 DPRINTF(MinorMem,
"Load request with stores still in transfers"
1038 " queue, stalling\n");
1043 if (bufferable && !request->
request->isLocalAccess()) {
1046 DPRINTF(MinorMem,
"Moving store into transfers queue\n");
1053 if (((!is_load && is_llsc) || is_release) &&
1055 DPRINTF(MinorMem,
"Memory access needs to wait for store buffer"
1065 DPRINTF(MinorMem,
"Memory access not the head inst., can't be"
1066 " sure it can be performed, not issuing\n");
1070 unsigned int forwarding_slot = 0;
1072 if (
storeBuffer.canForwardDataToLoad(request, forwarding_slot) !=
1082 DPRINTF(MinorMem,
"Memory access can receive forwarded data"
1083 " from the store buffer, but need to wait for store buffer"
1093 bool do_access =
true;
1098 unsigned int forwarding_slot = 0;
1103 switch (forwarding_result) {
1107 storeBuffer.forwardStoreData(request, forwarding_slot);
1114 DPRINTF(MinorMem,
"Load partly satisfied by store buffer"
1115 " data. Must wait for the store to complete\n");
1119 DPRINTF(MinorMem,
"No forwardable data from store buffer\n");
1126 DPRINTF(MinorMem,
"Can't send request to memory system yet\n");
1132 std::unique_ptr<PCStateBase> old_pc(thread.
pcState().
clone());
1143 DPRINTF(MinorMem,
"Not perfoming a memory "
1144 "access for store conditional\n");
1153 DPRINTF(MinorMem,
"Can't send request to memory system yet\n");
1179 DPRINTF(MinorMem,
"Can't send request: %s yet, no space in memory\n",
1184 DPRINTF(MinorMem,
"Trying to send request: %s addr: 0x%x\n",
1185 *(request->
inst), packet->
req->getVaddr());
1191 if (request->
request->isLocalAccess()) {
1193 cpu.getContext(
cpu.contextToThread(
1194 request->
request->contextId()));
1197 DPRINTF(MinorMem,
"IPR read inst: %s\n", *(request->
inst));
1199 DPRINTF(MinorMem,
"IPR write inst: %s\n", *(request->
inst));
1201 request->
request->localAccessor(thread, packet);
1207 DPRINTF(MinorMem,
"IPR access has another packet: %s\n",
1215 }
else if (
dcachePort.sendTimingReq(packet)) {
1216 DPRINTF(MinorMem,
"Sent data memory request\n");
1224 switch (request->
state) {
1238 panic(
"Unrecognized LSQ request state %d.", request->
state);
1244 "Sending data memory request - needs retry\n");
1250 switch (request->
state) {
1260 panic(
"Unrecognized LSQ request state %d.", request->
state);
1275 assert(
transfers.unreservedRemainingSpace() != 0);
1301 DPRINTF(MinorMem,
"Received response packet inst: %s"
1302 " addr: 0x%x cmd: %s\n",
1309 DPRINTF(MinorMem,
"Received error response packet: %s\n",
1313 switch (request->
state) {
1319 DPRINTF(MinorMem,
"Has outstanding packets?: %d %d\n",
1334 DPRINTF(MinorMem,
"Completed transfer for barrier: %s"
1335 " leaving the request as it is also a barrier\n",
1341 panic(
"Shouldn't be allowed to receive a response from another state");
1358 DPRINTF(MinorMem,
"Received retry request\n");
1402LSQ::LSQ(std::string name_, std::string dcache_port_name_,
1404 unsigned int in_memory_system_limit,
unsigned int line_width,
1405 unsigned int requests_queue_size,
unsigned int transfers_queue_size,
1406 unsigned int store_buffer_size,
1407 unsigned int store_buffer_cycle_store_limit) :
1415 lineWidth((line_width == 0 ?
cpu.cacheLineSize() : line_width)),
1416 requests(name_ +
".requests",
"addr", requests_queue_size),
1417 transfers(name_ +
".transfers",
"addr", transfers_queue_size),
1419 *this, store_buffer_size, store_buffer_cycle_store_limit),
1427 if (in_memory_system_limit < 1) {
1428 fatal(
"%s: executeMaxAccessesInMemory must be >= 1 (%d)\n", name_,
1429 in_memory_system_limit);
1432 if (store_buffer_cycle_store_limit < 1) {
1433 fatal(
"%s: executeLSQMaxStoreBufferStoresPerCycle must be"
1434 " >= 1 (%d)\n", name_, store_buffer_cycle_store_limit);
1437 if (requests_queue_size < 1) {
1438 fatal(
"%s: executeLSQRequestsQueueSize must be"
1439 " >= 1 (%d)\n", name_, requests_queue_size);
1442 if (transfers_queue_size < 1) {
1443 fatal(
"%s: executeLSQTransfersQueueSize must be"
1444 " >= 1 (%d)\n", name_, transfers_queue_size);
1447 if (store_buffer_size < 1) {
1448 fatal(
"%s: executeLSQStoreBufferSize must be"
1449 " >= 1 (%d)\n", name_, store_buffer_size);
1495 if (request->
inst->id == inst->id) {
1498 bool to_store_buffer = request->
state ==
1501 if ((complete && !(request->
isBarrier() && !can_store)) ||
1502 (to_store_buffer && can_store))
1510 DPRINTF(MinorMem,
"Found matching memory response for inst: %s\n",
1513 DPRINTF(MinorMem,
"No matching memory response for inst: %s\n",
1534 DPRINTF(MinorMem,
"Deleting %s request: %s\n",
1535 (response->
isLoad ?
"load" :
"store"),
1547 DPRINTF(MinorMem,
"Sending store: %s to store buffer\n",
1550 request->
inst->inStoreBuffer =
true;
1568 bool have_translated_requests = !
requests.empty() &&
1570 transfers.unreservedRemainingSpace() != 0;
1572 ret = have_translated_requests ||
1577 DPRINTF(Activity,
"Need to tick\n");
1588 assert(inst->translationFault ==
NoFault || inst->inLSQ);
1591 return inst->translationFault;
1596 if (needs_burst && inst->staticInst->isAtomic()) {
1604 panic(
"Do not expect cross-cache-line atomic memory request\n");
1611 uint8_t *request_data = NULL;
1613 DPRINTF(MinorMem,
"Pushing request (%s) addr: 0x%x size: %d flags:"
1614 " 0x%x%s lineWidth : 0x%x\n",
1615 (isLoad ?
"load" :
"store/atomic"),
addr, size, flags,
1616 (needs_burst ?
" (needs burst)" :
""),
lineWidth);
1621 request_data =
new uint8_t[size];
1622 if (inst->staticInst->isAtomic() ||
1625 std::memset(request_data, 0, size);
1627 std::memcpy(request_data,
data, size);
1633 *
this, inst, isLoad, request_data, res);
1636 *
this, inst, isLoad, request_data, res);
1639 if (inst->traceData)
1640 inst->traceData->setMem(
addr, size, flags);
1642 int cid =
cpu.threads[inst->id.threadId]->getTC()->contextId();
1643 request->
request->setContext(cid);
1645 addr, size, flags,
cpu.dataRequestorId(),
1647 inst->pc->instAddr(), std::move(amo_op));
1648 request->
request->setByteEnable(byte_enable);
1653 assert(!request->
request->isLocalAccess());
1654 request->
request->setLocalAccessor(
1662 return inst->translationFault;
1676 " lastMemBarrier=%d\n",
1685 unsigned int store_buffer_size,
1686 unsigned int store_limit_per_cycle) :
1707 }
else if (!request->isCacheMaintenance()) {
1719 assert(inst->isInst() && inst->staticInst->isFullMemBarrier());
1749 os <<
"MemoryRunning";
1752 os <<
"MemoryNeedsRetry";
1755 os <<
"MemoryState-" <<
static_cast<int>(
state);
1767 for (
ThreadID tid = 0; tid <
cpu.numThreads; tid++) {
1768 if (
cpu.getCpuAddrMonitor(tid)->doMonitor(pkt)) {
1774 for (
ThreadID tid = 0; tid <
cpu.numThreads; tid++) {
1775 cpu.getContext(tid)->getIsaPtr()->handleLockedSnoop(
1790 for (
ThreadID tid = 0; tid <
cpu.numThreads; tid++) {
1791 if (tid != req_tid) {
1792 if (
cpu.getCpuAddrMonitor(tid)->doMonitor(pkt)) {
1797 cpu.getContext(tid)->getIsaPtr()->handleLockedSnoop(pkt,
#define DPRINTFS(x, s,...)
virtual void handleLockedRead(const RequestPtr &req)
virtual bool handleLockedWrite(const RequestPtr &req, Addr cacheBlockMask)
virtual void translateTiming(const RequestPtr &req, ThreadContext *tc, Translation *translation, Mode mode)
Cycles is a wrapper class for representing cycle counts, i.e.
const std::string & toString() const
Return the string to a cmd given by idx.
MinorCPU is an in-order CPU model with four fixed pipeline stages:
Named(std::string_view name_)
virtual std::string name() const
virtual PCStateBase * clone() const =0
static PacketPtr createWrite(const RequestPtr &req)
void makeResponse()
Take a request packet and modify it in place to be suitable for returning as a response to that reque...
T * findNextSenderState() const
Go through the sender state stack and return the first instance that is of type T (as determined by a...
void pushSenderState(SenderState *sender_state)
Push a new sender state to the packet and make the current sender state the predecessor of the new on...
SenderState * popSenderState()
Pop the top of the state stack and return a pointer to it.
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.
const T * getConstPtr() const
void dataDynamic(T *p)
Set the data pointer to a value that should have delete [] called on it.
MemCmd cmd
The command field of the packet.
bool isInvalidate() const
void allocate()
Allocate memory for the packet.
@ NO_ACCESS
The request should not cause a memory access.
static const FlagsType STORE_NO_DATA
gem5::Flags< FlagsType > Flags
The SimpleThread object provides a combination of the ThreadState object and the ThreadContext interf...
const PCStateBase & pcState() const override
BaseISA * getIsaPtr() const override
ThreadContext is the external interface to all thread state for anything outside of the CPU.
virtual BaseMMU * getMMUPtr()=0
ExecContext bears the exec_context interface for Minor.
void setMemAccPredicate(bool val) override
Request for doing barrier accounting in the store buffer.
FailedDataRequest represents requests from instructions that failed their predicates but need to ride...
Derived SenderState to carry data access info.
static AddrRangeCoverage containsAddrRangeOf(Addr req1_addr, unsigned int req1_size, Addr req2_addr, unsigned int req2_size)
Does address range req1 (req1_addr to req1_addr + req1_size - 1) fully cover, partially cover or not ...
void tryToSuppressFault()
Instructions may want to suppress translation faults (e.g.
bool isTranslationDelayed
Address translation is delayed due to table walk.
bool needsToBeSentToStoreBuffer()
This request, once processed by the requests/transfers queues, will need to go to the store buffer.
RequestPtr request
The underlying request of this LSQRequest.
void makePacket()
Make a packet to use with the memory transaction.
bool isLoad
Load/store indication used for building packet.
void setState(LSQRequestState new_state)
Set state and output trace output.
bool issuedToMemory
This in an access other than a normal cacheable load that's visited the memory system.
void setSkipped()
Set this request as having been skipped before a memory transfer was attempt.
virtual bool sentAllPackets()=0
Have all packets been sent?
virtual PacketPtr getHeadPacket()=0
Get the next packet to issue for this request.
PacketDataPtr data
Dynamically allocated and populated data carried for building write packets.
void reportData(std::ostream &os) const
MinorTrace report interface.
virtual bool hasPacketsInMemSystem()=0
True if this request has any issued packets in the memory system and so can't be interrupted until it...
uint64_t * res
Res from pushRequest.
virtual void startAddrTranslation()=0
Start the address translation process for this request.
LSQRequest(LSQ &port_, MinorDynInstPtr inst_, bool isLoad_, PacketDataPtr data_=NULL, uint64_t *res_=NULL)
virtual void stepToNextPacket()=0
Step to the next packet for the next call to getHeadPacket.
MinorDynInstPtr inst
Instruction which made this request.
virtual bool isBarrier()
Is this a request a barrier?
void completeDisabledMemAccess()
bool isComplete() const
Has this request been completed.
virtual void retireResponse(PacketPtr packet_)=0
Retire a response packet into the LSQRequest packet possibly completing this transfer.
SingleDataRequest is used for requests that don't fragment.
void startAddrTranslation()
Send single translation request.
void finish(const Fault &fault_, const RequestPtr &request_, ThreadContext *tc, BaseMMU::Mode mode)
TLB interace.
bool packetInFlight
Has my only packet been sent to the memory system but has not yet been responded to.
void retireResponse(PacketPtr packet_)
Keep the given packet as the response packet LSQRequest::packet.
std::vector< Packet * > fragmentPackets
Packets matching fragmentRequests to issue fragments to memory.
void stepToNextPacket()
Step on numIssuedFragments.
unsigned int numTranslatedFragments
Number of fragments that have completed address translation, (numTranslatedFragments + numInTranslati...
EventFunctionWrapper translationEvent
Event to step between translations.
void finish(const Fault &fault_, const RequestPtr &request_, ThreadContext *tc, BaseMMU::Mode mode)
TLB response interface.
unsigned int numFragments
Number of fragments this request is split into.
unsigned int numInTranslationFragments
Number of fragments in the address translation mechanism.
std::vector< RequestPtr > fragmentRequests
Fragment Requests corresponding to the address ranges of each fragment.
void sendNextFragmentToTranslation()
Part of the address translation loop, see startAddTranslation.
unsigned int numIssuedFragments
Number of fragments already issued (<= numFragments)
void retireResponse(PacketPtr packet_)
For loads, paste the response data into the main response packet.
void makeFragmentRequests()
Make all the Requests for this transfer's fragments so that those requests can be sent for address tr...
bool hasPacketsInMemSystem()
True if this request has any issued packets in the memory system and so can't be interrupted until it...
PacketPtr getHeadPacket()
Get the head packet as counted by numIssuedFragments.
void makeFragmentPackets()
Make the packets to go with the requests so they can be sent to the memory system.
SplitDataRequest(LSQ &port_, MinorDynInstPtr inst_, bool isLoad_, PacketDataPtr data_=NULL, uint64_t *res_=NULL)
void startAddrTranslation()
Start a loop of do { sendNextFragmentToTranslation ; translateTiming ; finish } while (numTranslatedF...
unsigned int numRetiredFragments
Number of fragments retired back to this request.
void step()
Try to issue more stores to memory.
unsigned int numUnissuedAccesses
Number of occupied slots which have not yet issued a memory access.
AddrRangeCoverage canForwardDataToLoad(LSQRequestPtr request, unsigned int &found_slot)
Look for a store which satisfies the given load.
void forwardStoreData(LSQRequestPtr load, unsigned int slot_number)
Fill the given packet with appropriate date from slot slot_number.
const unsigned int storeLimitPerCycle
Maximum number of stores that can be issued per cycle.
void minorTrace() const
Report queue contents for MinorTrace.
StoreBuffer(std::string name_, LSQ &lsq_, unsigned int store_buffer_size, unsigned int store_limit_per_cycle)
const unsigned int numSlots
Number of slots, this is a bound on the size of slots.
std::deque< LSQRequestPtr > slots
Queue of store requests on their way to memory.
void countIssuedStore(LSQRequestPtr request)
Count a store being issued to memory by decrementing numUnissuedAccesses.
void insert(LSQRequestPtr request)
Insert a request at the back of the queue.
bool canInsert() const
Can a new request be inserted into the queue?
void deleteRequest(LSQRequestPtr request)
Delete the given request and free the slot it occupied.
void tryToSendToTransfers(LSQRequestPtr request)
Try and issue a memory access for a translated request at the head of the requests queue.
bool needsToTick()
May need to be ticked next cycle as one of the queues contains an actionable transfers or address tra...
void recvTimingSnoopReq(PacketPtr pkt)
void issuedMemBarrierInst(MinorDynInstPtr inst)
A memory barrier instruction has been issued, remember its execSeqNum that we can avoid issuing memor...
bool tryToSend(LSQRequestPtr request)
Try to send (or resend) a memory request's next/only packet to the memory system.
bool canSendToMemorySystem()
Can a request be sent to the memory system.
MemoryState
State of memory access for head access.
std::vector< InstSeqNum > lastMemBarrier
Most recent execSeqNum of a memory barrier instruction or 0 if there are no in-flight barriers.
unsigned int numAccessesInDTLB
Number of requests in the DTLB in the requests queue.
void sendStoreToStoreBuffer(LSQRequestPtr request)
A store has been committed, please move it to the store buffer.
void pushFailedRequest(MinorDynInstPtr inst)
Push a predicate failed-representing request into the queues just to maintain commit order.
LSQRequestPtr retryRequest
The request (from either requests or the store buffer) which is currently waiting have its memory acc...
void threadSnoop(LSQRequestPtr request)
Snoop other threads monitors on memory system accesses.
const Addr lineWidth
Memory system access width (and snap) in bytes.
AddrRangeCoverage
Coverage of one address range with another.
@ PartialAddrRangeCoverage
Fault pushRequest(MinorDynInstPtr 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=std::vector< bool >())
Single interface for readMem/writeMem/amoMem to issue requests into the LSQ.
unsigned int numAccessesInMemorySystem
Count of the number of mem.
unsigned int numAccessesIssuedToMemory
The number of accesses which have been issued to the memory system but have not been committed/discar...
LSQRequest * LSQRequestPtr
LSQ(std::string name_, std::string dcache_port_name_, MinorCPU &cpu_, Execute &execute_, unsigned int max_accesses_in_memory_system, unsigned int line_width, unsigned int requests_queue_size, unsigned int transfers_queue_size, unsigned int store_buffer_size, unsigned int store_buffer_cycle_store_limit)
const unsigned int inMemorySystemLimit
Maximum number of in-flight accesses issued to the memory system.
LSQQueue requests
requests contains LSQRequests which have been issued to the TLB by calling ExecContext::readMem/write...
unsigned int numStoresInTransfers
The number of stores in the transfers queue.
friend std::ostream & operator<<(std::ostream &os, MemoryState state)
Print MemoryState values as shown in the enum definition.
void step()
Step checks the queues to see if their are issuable transfers which were not otherwise picked up by t...
MemoryState state
Retry state of last issued memory transfer.
LSQQueue transfers
Once issued to memory (or, for stores, just had their state changed to StoreToStoreBuffer) LSQRequest...
void completeMemBarrierInst(MinorDynInstPtr inst, bool committed)
Complete a barrier instruction.
Addr cacheBlockMask
Address Mask for a cache block (e.g.
void popResponse(LSQRequestPtr response)
Sanity check and pop the head response.
MinorCPU & cpu
My owner(s)
void moveFromRequestsToTransfers(LSQRequestPtr request)
Move a request between queues.
LSQRequestPtr findResponse(MinorDynInstPtr inst)
Returns a response if it's at the head of the transfers queue and it's either complete or can be sent...
bool isDrained()
Is there nothing left in the LSQ.
bool recvTimingResp(PacketPtr pkt)
Memory interface.
void clearMemBarrier(MinorDynInstPtr inst)
Clear a barrier (if it's the last one marked up in lastMemBarrier)
All the fun of executing instructions from Decode and sending branch/new instruction stream info.
std::unique_ptr< AtomicOpFunctor > AtomicOpFunctorPtr
bool isSet(Type mask) const
Verifies whether any bit matching the given mask is set.
#define panic(...)
This implements a cprintf based panic() function.
#define fatal(...)
This implements a cprintf based fatal() function.
ExecContext bears the exec_context interface for Minor.
A load/store queue that allows outstanding reads and writes.
PacketPtr makePacketForRequest(const RequestPtr &request, bool isLoad, Packet::SenderState *sender_state, PacketDataPtr data)
Make a suitable packet for the given request.
RefCountingPtr< MinorDynInst > MinorDynInstPtr
MinorDynInsts are currently reference counted.
void minorTrace(const char *fmt, Args ...args)
DPRINTFN for MinorTrace reporting.
Copyright (c) 2024 Arm Limited All rights reserved.
std::shared_ptr< FaultBase > Fault
int16_t ThreadID
Thread index/ID type.
T safe_cast(U &&ref_or_ptr)
std::shared_ptr< Request > RequestPtr
Tick curTick()
The universal simulation clock.
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Addr addrBlockOffset(Addr addr, Addr block_size)
Calculates the offset of a given address wrt aligned fixed-size blocks.
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...
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.
The constructed pipeline.
A virtual base opaque structure used to hold state associated with the packet (e.g....