diff --git a/src/gpu-compute/fetch_unit.cc b/src/gpu-compute/fetch_unit.cc index fb04cd27e0..447ff12faa 100644 --- a/src/gpu-compute/fetch_unit.cc +++ b/src/gpu-compute/fetch_unit.cc @@ -234,6 +234,16 @@ FetchUnit::fetch(PacketPtr pkt, Wavefront *wavefront) 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 diff --git a/src/gpu-compute/fetch_unit.hh b/src/gpu-compute/fetch_unit.hh index 2cfe3f0fee..798c264655 100644 --- a/src/gpu-compute/fetch_unit.hh +++ b/src/gpu-compute/fetch_unit.hh @@ -120,6 +120,18 @@ class FetchUnit 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); /**