xref: /XiangShan/src/main/scala/xiangshan/backend/rename/freelist/BaseFreeList.scala (revision 3019c60115c6c7dc7dce289a5366f51d877c808f)
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