This changeset drops fetches if there is no entry reserved in the
fetch buffer for that instruction. This can happen due to a fetch
attempted to be issued in the same cycle where a branch instruction
flushed the fetch buffer, while an ITLB or I-cache request is still
pending.
Change-Id: I3b80dbd71af27ccf790b543bd5c034bb9b02624a
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/29932
Tested-by: kokoro <noreply+kokoro@google.com>
Reviewed-by: Anthony Gutierrez <anthony.gutierrez@amd.com>
Reviewed-by: Onur Kayıran <onur.kayiran@amd.com>
Maintainer: Anthony Gutierrez <anthony.gutierrez@amd.com>
pkt = new Packet(oldPkt->req, oldPkt->cmd);
delete oldPkt;
+ /**
+ * if we have not reserved an entry in the fetch buffer,
+ * stop fetching. this can happen due to a branch instruction
+ * flushing the fetch buffer while an ITLB or I-cache request is still
+ * pending, in the same cycle another instruction is trying to fetch.
+ */
+ if (!fetchBuf.at(wavefront->wfSlotId).isReserved(pkt->req->getVaddr())) {
+ return;
+ }
+
/**
* we should have reserved an entry in the fetch buffer
* for this cache line. here we get the pointer to the
return reserved_pc->second;
}
+ /**
+ * returns true if there is an entry reserved for this address,
+ * and false otherwise
+ */
+ bool
+ isReserved(Addr vaddr) const
+ {
+ auto reserved_pc = reservedPCs.find(vaddr);
+ bool is_reserved = (reserved_pc != reservedPCs.end());
+ return is_reserved;
+ }
+
void fetchDone(Addr vaddr);
/**