1/*************************************************************************************** 2* Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences 3* Copyright (c) 2020-2021 Peng Cheng Laboratory 4* 5* XiangShan is licensed under Mulan PSL v2. 6* You can use this software according to the terms and conditions of the Mulan PSL v2. 7* You may obtain a copy of Mulan PSL v2 at: 8* http://license.coscl.org.cn/MulanPSL2 9* 10* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, 11* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, 12* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. 13* 14* See the Mulan PSL v2 for more details. 15***************************************************************************************/ 16 17package xiangshan.backend.rename.freelist 18 19import org.chipsalliance.cde.config.Parameters 20import chisel3._ 21import chisel3.util._ 22import xiangshan._ 23import xiangshan.backend.rename.SnapshotGenerator 24import utils._ 25import utility._ 26 27 28abstract class BaseFreeList(size: Int, numLogicRegs:Int = 32)(implicit p: Parameters) extends XSModule with HasCircularQueuePtrHelper { 29 val io = IO(new Bundle { 30 val redirect = Input(Bool()) 31 val walk = Input(Bool()) 32 33 val allocateReq = Input(Vec(RenameWidth, Bool())) 34 val walkReq = Input(Vec(RabCommitWidth, Bool())) 35 val allocatePhyReg = Output(Vec(RenameWidth, UInt(PhyRegIdxWidth.W))) 36 val canAllocate = Output(Bool()) 37 val doAllocate = Input(Bool()) 38 39 val freeReq = Input(Vec(RabCommitWidth, Bool())) 40 val freePhyReg = Input(Vec(RabCommitWidth, UInt(PhyRegIdxWidth.W))) 41 42 val commit = Input(new RabCommitIO) 43 44 val snpt = Input(new SnapshotPort) 45 46 val debug_rat = if(backendParams.debugEn) Some(Vec(numLogicRegs, Input(UInt(PhyRegIdxWidth.W)))) else None 47 }) 48 49 class FreeListPtr extends CircularQueuePtr[FreeListPtr](size) 50 51 object FreeListPtr { 52 def apply(f: Boolean, v: Int): FreeListPtr = { 53 val ptr = Wire(new FreeListPtr) 54 ptr.flag := f.B 55 ptr.value := v.U 56 ptr 57 } 58 } 59 60 val lastCycleRedirect = RegNext(RegNext(io.redirect)) 61 val lastCycleSnpt = RegNext(RegNext(io.snpt, 0.U.asTypeOf(io.snpt))) 62 63 val headPtr = RegInit(FreeListPtr(false, 0)) 64 val headPtrOH = RegInit(1.U(size.W)) 65 val archHeadPtr = RegInit(FreeListPtr(false, 0)) 66 XSError(headPtr.toOH =/= headPtrOH, p"wrong one-hot reg between $headPtr and $headPtrOH") 67 val headPtrOHShift = CircularShift(headPtrOH) 68 // may shift [0, RenameWidth] steps 69 val headPtrOHVec = VecInit.tabulate(RenameWidth + 1)(headPtrOHShift.left) 70 71 val snapshots = SnapshotGenerator(headPtr, io.snpt.snptEnq, io.snpt.snptDeq, io.redirect, io.snpt.flushVec) 72 73 val redirectedHeadPtr = Mux( 74 lastCycleSnpt.useSnpt, 75 snapshots(lastCycleSnpt.snptSelect) + PopCount(io.walkReq), 76 archHeadPtr + PopCount(io.walkReq) 77 ) 78 val redirectedHeadPtrOH = Mux( 79 lastCycleSnpt.useSnpt, 80 (snapshots(lastCycleSnpt.snptSelect) + PopCount(io.walkReq)).toOH, 81 (archHeadPtr + PopCount(io.walkReq)).toOH 82 ) 83} 84