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