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