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