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