xref: /XiangShan/src/main/scala/utils/PipeWithFlush.scala (revision 3a76b099670e610ae7e0dc07e13f39079e87d06e)
1*3a76b099SXuan Hupackage utils
2*3a76b099SXuan Hu
3*3a76b099SXuan Huimport chisel3._
4*3a76b099SXuan Huimport chisel3.util._
5*3a76b099SXuan Huimport top.{ArgParser, BaseConfig, DefaultConfig}
6*3a76b099SXuan Huimport xiangshan._
7*3a76b099SXuan Huimport xiangshan.backend.Bundles.DynInst
8*3a76b099SXuan Hu
9*3a76b099SXuan Hu/** Pipeline module generator parameterized by data type and latency.
10*3a76b099SXuan Hu  *
11*3a76b099SXuan Hu  * @param gen a Chisel type, used as data in pipe
12*3a76b099SXuan Hu  * @param flushGen a Chisel type, used as flush signal
13*3a76b099SXuan Hu  * @param latency the number of pipeline stages
14*3a76b099SXuan Hu  * @param flushFunc used to generate flush signal
15*3a76b099SXuan Hu  * @tparam T Type of [[io.enq.bits]] and [[io.deq.bits]]
16*3a76b099SXuan Hu  * @tparam TFlush Type of [[io.flush]]
17*3a76b099SXuan Hu  */
18*3a76b099SXuan Huclass PipeWithFlush[T <: Data, TFlush <: Data] (
19*3a76b099SXuan Hu  val gen: T,
20*3a76b099SXuan Hu  val flushGen: TFlush,
21*3a76b099SXuan Hu  val latency: Int,
22*3a76b099SXuan Hu  flushFunc: (T, TFlush) => Bool
23*3a76b099SXuan Hu) extends Module {
24*3a76b099SXuan Hu  require(latency >= 0, "Pipe latency must be greater than or equal to zero!")
25*3a76b099SXuan Hu
26*3a76b099SXuan Hu  class PipeIO extends Bundle {
27*3a76b099SXuan Hu    val flush = Flipped(flushGen)
28*3a76b099SXuan Hu    val enq = Input(Valid(gen))
29*3a76b099SXuan Hu    val deq = Output(Valid(gen))
30*3a76b099SXuan Hu  }
31*3a76b099SXuan Hu
32*3a76b099SXuan Hu  val io = IO(new PipeIO)
33*3a76b099SXuan Hu
34*3a76b099SXuan Hu  if (latency == 0) {
35*3a76b099SXuan Hu    io.deq := io.enq
36*3a76b099SXuan Hu  } else {
37*3a76b099SXuan Hu    val valids: Seq[Bool] = io.enq.valid +: Seq.fill(latency)(RegInit(false.B))
38*3a76b099SXuan Hu    val bits: Seq[T] = io.enq.bits +: Seq.fill(latency)(Reg(gen))
39*3a76b099SXuan Hu
40*3a76b099SXuan Hu    for (i <- 0 until latency) {
41*3a76b099SXuan Hu      valids(i + 1) := valids(i) && !flushFunc(bits(i), io.flush)
42*3a76b099SXuan Hu      when (valids(i)) {
43*3a76b099SXuan Hu        bits(i + 1) := bits(i)
44*3a76b099SXuan Hu      }
45*3a76b099SXuan Hu    }
46*3a76b099SXuan Hu    io.deq.valid := valids.last
47*3a76b099SXuan Hu    io.deq.bits := bits.last
48*3a76b099SXuan Hu  }
49*3a76b099SXuan Hu}
50