1package xiangshan.backend.rename 2 3import org.chipsalliance.cde.config.Parameters 4import chisel3._ 5import chisel3.util._ 6import utility.{CircularQueuePtr, HasCircularQueuePtrHelper, XSError} 7import xiangshan.{XSCoreParamsKey, XSModule} 8 9 10class SnapshotPtr(implicit p: Parameters) extends CircularQueuePtr[SnapshotPtr]( 11 p => p(XSCoreParamsKey).RenameSnapshotNum 12) 13 14object SnapshotGenerator extends HasCircularQueuePtrHelper { 15 def apply[T <: Data](enqData: T, enq: Bool, deq: Bool, redirect: Bool, flushVec: Vec[Bool])(implicit p: Parameters): Vec[T] = { 16 val snapshotGen = Module(new SnapshotGenerator(enqData)) 17 snapshotGen.io.enq := enq 18 snapshotGen.io.enqData := enqData 19 snapshotGen.io.deq := deq 20 snapshotGen.io.redirect := redirect 21 snapshotGen.io.flushVec := flushVec 22 snapshotGen.io.snapshots 23 } 24} 25 26class SnapshotGenerator[T <: Data](dataType: T)(implicit p: Parameters) extends XSModule 27 with HasCircularQueuePtrHelper { 28 29 class SnapshotGeneratorIO extends Bundle { 30 val enq = Input(Bool()) 31 val enqData = Input(chiselTypeOf(dataType)) 32 val deq = Input(Bool()) 33 val redirect = Input(Bool()) 34 val flushVec = Input(Vec(RenameSnapshotNum, Bool())) 35 val snapshots = Output(Vec(RenameSnapshotNum, chiselTypeOf(dataType))) 36 val enqPtr = Output(new SnapshotPtr) 37 val deqPtr = Output(new SnapshotPtr) 38 val valids = Output(Vec(RenameSnapshotNum, Bool())) 39 } 40 41 val io = IO(new SnapshotGeneratorIO) 42 43 val snapshots = Reg(Vec(RenameSnapshotNum, chiselTypeOf(dataType))) 44 val snptEnqPtr = RegInit(0.U.asTypeOf(new SnapshotPtr)) 45 val snptDeqPtr = RegInit(0.U.asTypeOf(new SnapshotPtr)) 46 val snptValids = RegInit(VecInit.fill(RenameSnapshotNum)(false.B)) 47 48 io.snapshots := snapshots 49 io.enqPtr := snptEnqPtr 50 io.deqPtr := snptDeqPtr 51 io.valids := snptValids 52 53 when(!io.redirect && !isFull(snptEnqPtr, snptDeqPtr) && io.enq) { 54 snapshots(snptEnqPtr.value) := io.enqData 55 snptValids(snptEnqPtr.value) := true.B 56 snptEnqPtr := snptEnqPtr + 1.U 57 } 58 when(!io.redirect && io.deq) { 59 snptValids(snptDeqPtr.value) := false.B 60 snptDeqPtr := snptDeqPtr + 1.U 61 XSError(isEmpty(snptEnqPtr, snptDeqPtr), "snapshots should not be empty when dequeue!\n") 62 } 63 snptValids.zip(io.flushVec).foreach { case (valid, flush) => 64 when(flush) { valid := false.B } 65 } 66 when((Cat(io.flushVec) & Cat(snptValids)).orR) { 67 val newEnqPtrCandidate = (0 until RenameSnapshotNum).map(snptDeqPtr + _.U) 68 val newEnqPtrQualified = Wire(Vec(RenameSnapshotNum, Bool())) 69 newEnqPtrQualified.head := !snptValids(newEnqPtrCandidate.head.value) || io.flushVec(newEnqPtrCandidate.head.value) 70 newEnqPtrQualified.tail zip newEnqPtrCandidate.tail.zip(newEnqPtrCandidate.drop(1)).map { 71 case (thiz, last) => snptValids(last.value) && (!snptValids(thiz.value) || io.flushVec(thiz.value)) 72 } foreach (x => x._1 := x._2) 73 snptEnqPtr := MuxCase(newEnqPtrCandidate.last, newEnqPtrQualified.zip(newEnqPtrCandidate).dropRight(1)) 74 } 75} 76