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