未验证 提交 ddef3fab 编写于 作者: H Haojin Tang

wakeupQueue: flush pending wakeup requests when canceling

上级 b4361ce3
......@@ -2,9 +2,7 @@ package utils
import chisel3._
import chisel3.util._
import top.{ArgParser, BaseConfig, DefaultConfig}
import xiangshan._
import xiangshan.backend.Bundles.DynInst
/** Pipeline module generator parameterized by data type and latency.
*
......@@ -16,34 +14,30 @@ import xiangshan.backend.Bundles.DynInst
* @tparam TFlush Type of [[io.flush]]
*/
class PipeWithFlush[T <: Data, TFlush <: Data] (
val gen: T,
val flushGen: TFlush,
val latency: Int,
flushFunc: (T, TFlush) => Bool
gen: T,
flushGen: TFlush,
latency: Int,
flushFunc: (T, TFlush, Int) => Bool
) extends Module {
require(latency >= 0, "Pipe latency must be greater than or equal to zero!")
class PipeIO extends Bundle {
val flush = Flipped(flushGen)
val flush = Input(flushGen)
val enq = Input(Valid(gen))
val deq = Output(Valid(gen))
}
val io = IO(new PipeIO)
if (latency == 0) {
io.deq := io.enq
} else {
val valids: Seq[Bool] = io.enq.valid +: Seq.fill(latency)(RegInit(false.B))
val bits: Seq[T] = io.enq.bits +: Seq.fill(latency)(Reg(gen))
val valids: Seq[Bool] = io.enq.valid +: Seq.fill(latency)(RegInit(false.B))
val bits: Seq[T] = io.enq.bits +: Seq.fill(latency)(Reg(gen))
for (i <- 0 until latency) {
valids(i + 1) := valids(i) && !flushFunc(bits(i), io.flush)
when (valids(i)) {
bits(i + 1) := bits(i)
}
for (i <- 0 until latency) {
valids(i + 1) := valids(i) && !flushFunc(bits(i), io.flush, i)
when (valids(i)) {
bits(i + 1) := bits(i)
}
io.deq.valid := valids.last
io.deq.bits := bits.last
}
io.deq.valid := valids.last
io.deq.bits := bits.last
}
......@@ -92,13 +92,24 @@ class IssueQueueImp(override val wrapper: IssueQueue)(implicit p: Parameters, va
val vfWbBusyTableWrite = params.exuBlockParams.map { case x => OptionWrapper(x.vfLatencyCertain, Module(new FuBusyTableWrite(x.vfFuLatencyMap))) }
val vfWbBusyTableRead = params.exuBlockParams.map { case x => OptionWrapper(x.vfLatencyCertain, Module(new FuBusyTableRead(x.vfFuLatencyMap))) }
val wakeUpQueues: Seq[Option[MultiWakeupQueue[ExuInput, ValidIO[Redirect]]]] = params.exuBlockParams.map { x => OptionWrapper(x.isIQWakeUpSource, Module(
new MultiWakeupQueue(
new ExuInput(x),
ValidIO(new Redirect) ,
x.fuLatancySet,
(exuInput: ExuInput, flush: ValidIO[Redirect]) => exuInput.robIdx.needFlush(flush)
)
class WakeupQueueFlush extends Bundle {
val redirect = ValidIO(new Redirect)
val og0Fail = Output(Bool())
val og1Fail = Output(Bool())
}
private def flushFunc(exuInput: ExuInput, flush: WakeupQueueFlush, stage: Int): Bool = {
val redirectFlush = exuInput.robIdx.needFlush(flush.redirect)
val ogFailFlush = stage match {
case 1 => flush.og0Fail
case 2 => flush.og1Fail
case _ => false.B
}
redirectFlush || ogFailFlush
}
val wakeUpQueues: Seq[Option[MultiWakeupQueue[ExuInput, WakeupQueueFlush]]] = params.exuBlockParams.map { x => OptionWrapper(x.isIQWakeUpSource, Module(
new MultiWakeupQueue(new ExuInput(x), new WakeupQueueFlush, x.fuLatancySet, flushFunc)
))}
val intWbBusyTableIn = io.wbBusyTableRead.map(_.intWbBusyTable)
......@@ -414,7 +425,11 @@ class IssueQueueImp(override val wrapper: IssueQueue)(implicit p: Parameters, va
wakeUpQueues.zipWithIndex.foreach { case (wakeUpQueueOption, i) =>
wakeUpQueueOption.foreach {
wakeUpQueue =>
wakeUpQueue.io.flush := io.flush
val flush = Wire(new WakeupQueueFlush)
flush.redirect := io.flush
flush.og0Fail := io.og0Resp(i).valid && RSFeedbackType.isBlocked(io.og0Resp(i).bits.respType)
flush.og1Fail := io.og1Resp(i).valid && RSFeedbackType.isBlocked(io.og1Resp(i).bits.respType)
wakeUpQueue.io.flush := flush
wakeUpQueue.io.enq.valid := io.deq(i).fire && !io.deq(i).bits.common.needCancel(io.og0Cancel, io.og1Cancel) && {
if (io.deq(i).bits.common.rfWen.isDefined)
io.deq(i).bits.common.rfWen.get && io.deq(i).bits.common.pdest =/= 0.U
......@@ -423,6 +438,8 @@ class IssueQueueImp(override val wrapper: IssueQueue)(implicit p: Parameters, va
}
wakeUpQueue.io.enq.bits.uop := io.deq(i).bits.common
wakeUpQueue.io.enq.bits.lat := getDeqLat(i, io.deq(i).bits.common.fuType)
wakeUpQueue.io.og0IssueFail := flush.og0Fail
wakeUpQueue.io.og1IssueFail := flush.og1Fail
}
}
......
......@@ -14,8 +14,10 @@ class MultiWakeupQueueIO[T <: Data, TFlush <: Data](
val lat = Output(UInt(latWidth.W))
}
val flush = Flipped(flushGen)
val flush = Input(flushGen)
val enq = Flipped(Valid(new EnqBundle))
val og0IssueFail = Input(Bool())
val og1IssueFail = Input(Bool())
val deq = Output(Valid(gen))
}
......@@ -23,7 +25,7 @@ class MultiWakeupQueue[T <: Data, TFlush <: Data](
val gen : T,
val flushGen : TFlush,
val latencySet: Set[Int],
flushFunc : (T, TFlush) => Bool,
flushFunc : (T, TFlush, Int) => Bool
) extends Module {
require(latencySet.min >= 0)
......@@ -31,14 +33,18 @@ class MultiWakeupQueue[T <: Data, TFlush <: Data](
val pipes = latencySet.map(x => Module(new PipeWithFlush[T, TFlush](gen, flushGen, x, flushFunc))).toSeq
pipes.zipWithIndex.foreach {
case (pipe, i) =>
pipes.zip(latencySet).foreach {
case (pipe, lat) =>
pipe.io.flush := io.flush
pipe.io.enq.valid := io.enq.valid && io.enq.bits.lat === i.U
pipe.io.enq.valid := io.enq.valid && io.enq.bits.lat === lat.U
pipe.io.enq.bits := io.enq.bits.uop
}
private val pipesValidVec = VecInit(pipes.map(_.io.deq.valid))
private val pipesValidVec = VecInit(pipes.map(_.io.deq.valid).zip(latencySet).map(_ match {
case (valid, 1) => valid && !io.og0IssueFail
case (valid, 2) => valid && !io.og1IssueFail
case (valid, _) => valid
}))
private val pipesBitsVec = VecInit(pipes.map(_.io.deq.bits))
io.deq.valid := pipesValidVec.asUInt.orR
......
......@@ -16,7 +16,7 @@ object MultiWakeupQueueMain extends App {
new DynInst()(p),
ValidIO(new Redirect()(p)),
Set(2, 4),
(dynInst: DynInst, flush: ValidIO[Redirect]) => dynInst.robIdx.needFlush(flush)
(dynInst: DynInst, flush: ValidIO[Redirect], stage: Int) => dynInst.robIdx.needFlush(flush)
),
Array("--full-stacktrace", "--target-dir", "build/issue")
)
......
......@@ -17,7 +17,7 @@ object GenPipeWithFlush extends App {
new DynInst()(p),
ValidIO(new Redirect()(p)),
2,
(dynInst: DynInst, flush: ValidIO[Redirect]) => dynInst.robIdx.needFlush(flush)
(dynInst: DynInst, flush: ValidIO[Redirect], stage: Int) => dynInst.robIdx.needFlush(flush)
),
Array("--target-dir", "build/vifu"))
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册