Skip to content

Commit

Permalink
IBuffer: fix a bypass bug when decode stage can not accept all the by…
Browse files Browse the repository at this point in the history
…pass insts (OpenXiangShan#2985)
  • Loading branch information
xiaofeibao-xjtu authored May 17, 2024
1 parent c83747b commit e778bb8
Showing 1 changed file with 24 additions and 5 deletions.
29 changes: 24 additions & 5 deletions src/main/scala/xiangshan/frontend/IBuffer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -164,10 +164,14 @@ class IBuffer(implicit p: Parameters) extends XSModule with HasCircularQueuePtrH
val numTryEnq = WireDefault(0.U)
val numEnq = Mux(io.in.fire, numTryEnq, 0.U)

val useBypass = enqPtr === deqPtr && decodeCanAccept // empty and decode can accept insts
// Record the insts in output entries are from bypass or deq.
// Update deqPtr if they are from deq
val currentOutUseBypass = RegInit(false.B)
val numBypassRemain = RegInit(0.U(log2Up(DecodeWidth).W))
val numBypassRemainNext = Wire(numBypassRemain.cloneType)

// empty and decode can accept insts and previous bypass insts are all out
val useBypass = enqPtr === deqPtr && decodeCanAccept && (numBypassRemain === 0.U || currentOutUseBypass && numBypassRemainNext === 0.U)

// The number of decode accepted insts.
// Since decode promises accepting insts in order, use priority encoder to simplify the accumulation.
Expand Down Expand Up @@ -225,18 +229,31 @@ class IBuffer(implicit p: Parameters) extends XSModule with HasCircularQueuePtrH
io.valid := reg.valid
io.bits := reg.bits.toCtrlFlow
}
outputEntries zip bypassEntries zip deqEntries foreach {
case ((out, bypass), deq) =>
(outputEntries zip bypassEntries zip deqEntries).zipWithIndex.foreach {
case (((out, bypass), deq), i) =>
when(decodeCanAccept) {
out := deq
currentOutUseBypass := false.B
when(useBypass && io.in.valid) {
out := bypass
currentOutUseBypass := true.B
}.elsewhen(currentOutUseBypass && numBypassRemainNext =/= 0.U) {
out := Mux(i.U < numBypassRemainNext, outputEntries(i.U + numOut), 0.U.asTypeOf(out))
currentOutUseBypass := true.B
}.otherwise {
out := deq
currentOutUseBypass := false.B
}
}
}

when(useBypass && io.in.valid) {
numBypassRemain := numBypass
}.elsewhen(currentOutUseBypass) {
numBypassRemain := numBypassRemainNext
}.otherwise {
assert(numBypassRemain === 0.U, "numBypassRemain should keep 0 when not in currentOutUseBypass")
}
numBypassRemainNext := numBypassRemain - numOut

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Enqueue
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -315,6 +332,8 @@ class IBuffer(implicit p: Parameters) extends XSModule with HasCircularQueuePtrH
deqInBankPtr := VecInit.fill(IBufNBank)(0.U.asTypeOf(new IBufInBankPtr))
deqPtr := 0.U.asTypeOf(new IBufPtr())
outputEntries.foreach(_.valid := false.B)
currentOutUseBypass := false.B
numBypassRemain := 0.U
}.otherwise {
deqPtr := deqPtrNext
deqInBankPtr := deqInBankPtrNext
Expand Down

0 comments on commit e778bb8

Please sign in to comment.