diff --git a/src/main/scala/nutcore/frontend/BPU.scala b/src/main/scala/nutcore/frontend/BPU.scala index 73db3826..88fab717 100644 --- a/src/main/scala/nutcore/frontend/BPU.scala +++ b/src/main/scala/nutcore/frontend/BPU.scala @@ -102,7 +102,7 @@ class BPU_ooo extends NutCoreModule { // we should latch the input pc for one cycle val pcLatch = RegEnable(io.in.pc.bits, io.in.pc.valid) val btbHit = Wire(Vec(4, Bool())) - (0 to 3).map(i => btbHit(i) := btbRead(i).valid && btbRead(i).tag === btbAddr.getTag(pcLatch) && !flush && RegNext(btb(i).io.r.req.fire, init = false.B)) + (0 to 3).map(i => btbHit(i) := btbRead(i).valid && btbRead(i).tag === btbAddr.getTag(pcLatch) && !flush && RegNext(btb(i).io.r.req.ready, init = false.B)) // btbHit will ignore pc(2,0). pc(2,0) is used to build brIdx val crosslineJump = btbRead(3).crosslineJump && btbHit(3) && !io.brIdx(0) && !io.brIdx(1) && !io.brIdx(2) io.crosslineJump := crosslineJump @@ -317,7 +317,10 @@ class BPU_inorder extends NutCoreModule { // since there is one cycle latency to read SyncReadMem, // we should latch the input pc for one cycle val pcLatch = RegEnable(io.in.pc.bits, io.in.pc.valid) - val btbHit = btbRead.valid && btbRead.tag === btbAddr.getTag(pcLatch) && !flush && RegNext(btb.io.r.req.fire, init = false.B) && !(pcLatch(1) && btbRead.brIdx(0)) + val btbHit = btbRead.valid && btbRead.tag === btbAddr.getTag(pcLatch) && !flush && RegNext(btb.io.r.req.ready, init = false.B) && !(pcLatch(1) && btbRead.brIdx(0)) + // btb.io.r.req.ready is used to indicate whether BTB SRAM is doing reset (if is true.B, btbRead.valid can be fake) + // we don't use btb.io.r.req.fire because of btb.io.r.req.valid only last for 1 cycle, further causes fake BTB miss + // See https://github.com/OSCPU/NutShell/pull/147 // btbHit will ignore pc(1,0). pc(1,0) is used to build brIdx // !(pcLatch(1) && btbRead.brIdx(0)) is used to deal with the following case: // -------------------------------------------------