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