1a8db15d8Sfdypackage xiangshan.backend.rob 2a8db15d8Sfdy 3a8db15d8Sfdyimport chipsalliance.rocketchip.config.Parameters 4a8db15d8Sfdyimport chisel3._ 5a8db15d8Sfdyimport chisel3.util._ 6a8db15d8Sfdyimport xiangshan._ 7a8db15d8Sfdyimport utils._ 8a8db15d8Sfdyimport utility._ 9a8db15d8Sfdyimport xiangshan.backend.Bundles.DynInst 10a8db15d8Sfdyimport xiangshan.backend.decode.VectorConstants 11a8db15d8Sfdy 12a8db15d8Sfdyclass RenameBuffer(size: Int)(implicit p: Parameters) extends XSModule with HasCircularQueuePtrHelper { 13a8db15d8Sfdy val io = IO(new Bundle { 14a8db15d8Sfdy val redirectValid = Input(Bool()) 15a8db15d8Sfdy 16a8db15d8Sfdy val req = Vec(RenameWidth, Flipped(ValidIO(new DynInst))) 17a8db15d8Sfdy val canEnq = Output(Bool()) 18a8db15d8Sfdy 19a8db15d8Sfdy val walkSize = Input(UInt(log2Up(size).W)) 20a8db15d8Sfdy val robWalkEnd = Input(Bool()) 21a8db15d8Sfdy val commitSize = Input(UInt(log2Up(size).W)) 22a8db15d8Sfdy val rabWalkEnd = Output(Bool()) 23a8db15d8Sfdy 24a8db15d8Sfdy val vconfigPdest = Output(UInt(PhyRegIdxWidth.W)) 25a8db15d8Sfdy 26a8db15d8Sfdy val commits = Output(new RobCommitIO) 27a8db15d8Sfdy val diffCommits = Output(new DiffCommitIO) 28a8db15d8Sfdy }) 29a8db15d8Sfdy 30a8db15d8Sfdy class RenameBufferPtr extends CircularQueuePtr[RenameBufferPtr](size) 31a8db15d8Sfdy 32a8db15d8Sfdy object RenameBufferPtr { 33a8db15d8Sfdy def apply(f: Boolean, v: Int): RenameBufferPtr = { 34a8db15d8Sfdy val ptr = Wire(new RenameBufferPtr) 35a8db15d8Sfdy ptr.flag := f.B 36a8db15d8Sfdy ptr.value := v.U 37a8db15d8Sfdy ptr 38a8db15d8Sfdy } 39a8db15d8Sfdy } 40a8db15d8Sfdy 41a8db15d8Sfdy val s_idle :: s_walk :: s_cancel :: Nil = Enum(3) 42a8db15d8Sfdy val state = RegInit(s_idle) 43a8db15d8Sfdy val stateNxt = WireInit(s_idle) 44a8db15d8Sfdy 45a8db15d8Sfdy val robWalkEnd = RegInit(false.B) 46a8db15d8Sfdy 47a8db15d8Sfdy when(io.redirectValid){ 48a8db15d8Sfdy robWalkEnd := false.B 49a8db15d8Sfdy }.elsewhen(io.robWalkEnd){ 50a8db15d8Sfdy robWalkEnd := true.B 51a8db15d8Sfdy } 52a8db15d8Sfdy 53a8db15d8Sfdy val renameBuffer = RegInit(VecInit(Seq.fill(size){0.U.asTypeOf(new RobCommitInfo)})) 54a8db15d8Sfdy 55a8db15d8Sfdy // pointer 56a8db15d8Sfdy // tail: enq and walk 57a8db15d8Sfdy // head: commit to arch rat 58a8db15d8Sfdy // diff: commit to diff rat 59a8db15d8Sfdy val headPtr = RegInit(RenameBufferPtr(false, 0)) 60a8db15d8Sfdy val headPtrOH = RegInit(1.U(size.W)) 61a8db15d8Sfdy XSError(headPtr.toOH =/= headPtrOH, p"wrong one-hot reg between $headPtr and $headPtrOH") 62a8db15d8Sfdy val headPtrOHShift = CircularShift(headPtrOH) 63a8db15d8Sfdy // may shift [0, CommitWidth] steps 64a8db15d8Sfdy val headPtrOHVec = VecInit.tabulate(CommitWidth + 1)(headPtrOHShift.left) 65*3938b56dSzhanglyGit val headPtrOHVec2 = VecInit(Seq.tabulate(CommitWidth * MaxUopSize + 1)(_ % size).map(step => headPtrOHShift.left(step))) 66a8db15d8Sfdy 67a8db15d8Sfdy val vcfgPtrOH = RegInit(1.U(size.W)) 68a8db15d8Sfdy val vcfgPtrOHShift = CircularShift(vcfgPtrOH) 69a8db15d8Sfdy // may shift [0, 2) steps 70a8db15d8Sfdy val vcfgPtrOHVec = VecInit.tabulate(2)(vcfgPtrOHShift.left) 71a8db15d8Sfdy 72a8db15d8Sfdy val diffPtrOH = RegInit(1.U(size.W)) 73a8db15d8Sfdy val diffPtrOHShift = CircularShift(diffPtrOH) 74a8db15d8Sfdy // may shift [0, CommitWidth * MaxUopSize] steps 75*3938b56dSzhanglyGit val diffPtrOHVec = VecInit(Seq.tabulate(CommitWidth * MaxUopSize + 1)(_ % size).map(step => diffPtrOHShift.left(step))) 76a8db15d8Sfdy 77a8db15d8Sfdy val tailPtr = RegInit(RenameBufferPtr(false, 0)) 78a8db15d8Sfdy val tailPtrOH = RegInit(1.U(size.W)) 79a8db15d8Sfdy val tailPtrOHShift = CircularShift(tailPtrOH) 80a8db15d8Sfdy // may shift [0, RenameWidth] steps 81a8db15d8Sfdy val tailPtrOHVec = VecInit.tabulate(RenameWidth + 1)(tailPtrOHShift.left) 82a8db15d8Sfdy val tailPtrVec = RegInit(VecInit.tabulate(RenameWidth)(_.U.asTypeOf(new RenameBufferPtr))) 83a8db15d8Sfdy 84a8db15d8Sfdy val realNeedAlloc = io.req.map(req => req.valid && req.bits.needWriteRf) 85a8db15d8Sfdy val enqCount = PopCount(realNeedAlloc) 86a8db15d8Sfdy val commitCount = PopCount(io.commits.commitValid) 87a8db15d8Sfdy val walkCount = PopCount(io.commits.walkValid) 88a8db15d8Sfdy 89a8db15d8Sfdy // number of pair(ldest, pdest) ready to commit to arch_rat 90a8db15d8Sfdy val commitSize = RegInit(0.U(log2Up(size).W)) 91a8db15d8Sfdy val commitSizeNxt = Mux(state === s_idle, commitSize - Mux(io.commits.isCommit, commitCount, 0.U) + io.commitSize, commitSize) 92a8db15d8Sfdy commitSize := commitSizeNxt 93a8db15d8Sfdy val walkSize = RegInit(0.U(log2Up(size).W)) 94a8db15d8Sfdy val walkSizeNxt = walkSize + io.walkSize - walkCount 95a8db15d8Sfdy walkSize := Mux(io.redirectValid, commitSizeNxt, walkSizeNxt) 96a8db15d8Sfdy 97a8db15d8Sfdy val rabWalkEnd = robWalkEnd === true.B && walkSizeNxt === 0.U 98a8db15d8Sfdy 99a8db15d8Sfdy val walkCandidates = VecInit(tailPtrOHVec.map(sel => Mux1H(sel, renameBuffer))) 100a8db15d8Sfdy val commitCandidates = VecInit(headPtrOHVec.map(sel => Mux1H(sel, renameBuffer))) 101a8db15d8Sfdy val vcfgCandidates = VecInit(vcfgPtrOHVec.map(sel => Mux1H(sel, renameBuffer))) 102a8db15d8Sfdy val diffCandidates = VecInit(diffPtrOHVec.map(sel => Mux1H(sel, renameBuffer))) 103a8db15d8Sfdy 104a8db15d8Sfdy // update head pointer 105a8db15d8Sfdy val headPtrNext = headPtr + commitCount 106a8db15d8Sfdy val headPtrOHNext = headPtrOHVec(commitCount) 107a8db15d8Sfdy headPtr := headPtrNext 108a8db15d8Sfdy headPtrOH := headPtrOHNext 109a8db15d8Sfdy // update diff pointer 110a8db15d8Sfdy val diffPtrOHNext = Mux(state === s_idle, diffPtrOHVec(io.commitSize), diffPtrOH) 111a8db15d8Sfdy diffPtrOH := diffPtrOHNext 112a8db15d8Sfdy // update vcfg pointer 113a8db15d8Sfdy vcfgPtrOH := diffPtrOHNext 114a8db15d8Sfdy // update tail pointer 115a8db15d8Sfdy val tailPtrEnqNext = tailPtr + PopCount(realNeedAlloc) 116a8db15d8Sfdy val tailPtrWalkNext = tailPtr + walkCount 117a8db15d8Sfdy val tailPtrNext = Mux(io.redirectValid, headPtrNext, 118a8db15d8Sfdy Mux(io.commits.isWalk, tailPtrWalkNext, tailPtrEnqNext)) 119a8db15d8Sfdy val tailPtrOHNext = Mux(io.redirectValid, headPtrOHVec2(commitCount), 120a8db15d8Sfdy Mux(io.commits.isWalk, tailPtrOHVec(walkCount), tailPtrOHVec(PopCount(realNeedAlloc)))) 121a8db15d8Sfdy tailPtr := tailPtrNext 122a8db15d8Sfdy tailPtrOH := tailPtrOHNext 123a8db15d8Sfdy tailPtrVec.zipWithIndex.map{ case(ptr, i) => ptr := tailPtrNext + i.U} 124a8db15d8Sfdy 125a8db15d8Sfdy val allocatePtrVec = VecInit((0 until RenameWidth).map(i => tailPtrVec(PopCount(realNeedAlloc.take(i))).value)) 126a8db15d8Sfdy allocatePtrVec.zip(io.req).zip(realNeedAlloc).map{ case((allocatePtr, req), realNeedAlloc) => 127a8db15d8Sfdy when(realNeedAlloc){ 128a8db15d8Sfdy renameBuffer(allocatePtr).ldest := req.bits.ldest 129a8db15d8Sfdy renameBuffer(allocatePtr).pdest := req.bits.pdest 130a8db15d8Sfdy renameBuffer(allocatePtr).old_pdest := req.bits.oldPdest 131a8db15d8Sfdy renameBuffer(allocatePtr).rfWen := req.bits.rfWen 132a8db15d8Sfdy renameBuffer(allocatePtr).fpWen := req.bits.fpWen 133a8db15d8Sfdy renameBuffer(allocatePtr).vecWen := req.bits.vecWen 134a8db15d8Sfdy renameBuffer(allocatePtr).isMove := req.bits.eliminatedMove 135a8db15d8Sfdy } 136a8db15d8Sfdy } 137a8db15d8Sfdy 138a8db15d8Sfdy io.commits.isCommit := state === s_idle 139a8db15d8Sfdy io.commits.isWalk := state === s_walk 140a8db15d8Sfdy 141a8db15d8Sfdy for(i <- 0 until CommitWidth) { 142a8db15d8Sfdy io.commits.commitValid(i) := state === s_idle && i.U < commitSize 143a8db15d8Sfdy io.commits.walkValid(i) := state === s_walk && i.U < walkSize 144a8db15d8Sfdy io.commits.info(i) := Mux(state === s_idle, commitCandidates(i), walkCandidates(i)) 145a8db15d8Sfdy } 146a8db15d8Sfdy 147a8db15d8Sfdy stateNxt := Mux(io.redirectValid, s_walk, 148a8db15d8Sfdy Mux(state === s_walk && rabWalkEnd, s_idle, state)) 149a8db15d8Sfdy state := stateNxt 150a8db15d8Sfdy 151a8db15d8Sfdy io.rabWalkEnd := state === s_walk && rabWalkEnd 152a8db15d8Sfdy 153a8db15d8Sfdy val allowEnqueue = RegInit(true.B) 154a8db15d8Sfdy val numValidEntries = distanceBetween(tailPtr, headPtr) 155a8db15d8Sfdy allowEnqueue := numValidEntries + enqCount <= (size - RenameWidth).U 156a8db15d8Sfdy io.canEnq := allowEnqueue 157a8db15d8Sfdy 158fe60541bSXuan Hu io.vconfigPdest := Mux(vcfgCandidates(0).ldest === VCONFIG_IDX.U && vcfgCandidates(0).vecWen, vcfgCandidates(0).pdest, vcfgCandidates(1).pdest) 159a8db15d8Sfdy 160a8db15d8Sfdy // for difftest 161a8db15d8Sfdy io.diffCommits := 0.U.asTypeOf(new DiffCommitIO) 162a8db15d8Sfdy io.diffCommits.isCommit := state === s_idle 163a8db15d8Sfdy for(i <- 0 until CommitWidth * MaxUopSize) { 164a8db15d8Sfdy io.diffCommits.commitValid(i) := state === s_idle && i.U < io.commitSize 165a8db15d8Sfdy io.diffCommits.info(i) := diffCandidates(i) 166a8db15d8Sfdy } 167a8db15d8Sfdy 168a8db15d8Sfdy} 169