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