xref: /XiangShan/src/main/scala/xiangshan/backend/datapath/PcTargetMem.scala (revision 9477429f7dc92dfd72de3908b8e953de2886a01d)
1package xiangshan.backend
2
3import org.chipsalliance.cde.config.Parameters
4import chisel3._
5import chisel3.util._
6import freechips.rocketchip.diplomacy.{LazyModule, LazyModuleImp}
7import utility._
8import xiangshan._
9import xiangshan.backend.datapath.DataConfig.VAddrData
10import xiangshan.frontend.{FtqPtr, FtqToCtrlIO, Ftq_RF_Components}
11
12class PcTargetMem(params: BackendParams)(implicit p: Parameters) extends LazyModule {
13  override def shouldBeInlined: Boolean = false
14
15  lazy val module = new PcTargetMemImp(this)(p, params)
16}
17
18class PcTargetMemImp(override val wrapper: PcTargetMem)(implicit p: Parameters, params: BackendParams) extends LazyModuleImp(wrapper) with HasXSParameter {
19
20  private val numTargetMemRead = params.numTargetReadPort + params.numPcMemReadPort
21  val io = IO(new PcTargetMemIO())
22
23  private def hasRen: Boolean = true
24  private val targetMem = Module(new SyncDataModuleTemplate(new Ftq_RF_Components, FtqSize, numTargetMemRead, 1, hasRen = hasRen))
25  private val jumpTargetReadVec : Vec[UInt] = Wire(Vec(params.numTargetReadPort, UInt(VAddrData().dataWidth.W)))
26  private val jumpTargetVec     : Vec[UInt] = Wire(Vec(params.numTargetReadPort, UInt(VAddrData().dataWidth.W)))
27
28  targetMem.io.wen.head := RegNext(io.fromFrontendFtq.pc_mem_wen)
29  targetMem.io.waddr.head := RegEnable(io.fromFrontendFtq.pc_mem_waddr, io.fromFrontendFtq.pc_mem_wen)
30  targetMem.io.wdata.head := RegEnable(io.fromFrontendFtq.pc_mem_wdata, io.fromFrontendFtq.pc_mem_wen)
31
32  private val newestEn: Bool = io.fromFrontendFtq.newest_entry_en
33  private val newestTarget: UInt = io.fromFrontendFtq.newest_entry_target
34  for (i <- 0 until params.numTargetReadPort) {
35    val targetVld = io.fromDataPathVld(i)
36    val targetPtr = io.fromDataPathFtq(i)
37    // target pc stored in next entry
38    targetMem.io.ren.get(i) := targetVld
39    targetMem.io.raddr(i) := (targetPtr + 1.U).value
40    jumpTargetReadVec(i) := targetMem.io.rdata(i).startAddr
41    val needNewestTarget = RegNext(targetPtr === io.fromFrontendFtq.newest_entry_ptr)
42    jumpTargetVec(i) := Mux(
43      needNewestTarget,
44      RegEnable(newestTarget, newestEn),
45      jumpTargetReadVec(i)
46    )
47  }
48  private val pcReadVec = Wire(Vec(params.numPcMemReadPort, UInt(VAddrData().dataWidth.W)))
49  private val pcVec = Wire(Vec(params.numPcMemReadPort, UInt(VAddrData().dataWidth.W)))
50  for (i <- 0 until params.numPcMemReadPort) {
51    val vld = io.pcToDataPath.fromDataPathFtqVld(i)
52    val pcAddr = io.pcToDataPath.fromDataPathFtqPtr(i)
53    // pc stored in this entry
54    val offset = io.pcToDataPath.fromDataPathFtqOffset(i)
55    targetMem.io.ren.get(i + params.numTargetReadPort) := vld
56    targetMem.io.raddr(i + params.numTargetReadPort) := pcAddr.value
57    pcReadVec(i) := targetMem.io.rdata(i + params.numTargetReadPort).getPc(RegNext(offset))
58    pcVec(i) := pcReadVec(i)
59  }
60  io.pcToDataPath.toDataPathPC := pcVec
61  io.toExus := jumpTargetVec
62
63}
64
65class PcToDataPathIO(params: BackendParams)(implicit p: Parameters) extends XSBundle {
66  val toDataPathPC = Output(Vec(params.numPcMemReadPort, UInt(VAddrData().dataWidth.W)))
67  val fromDataPathFtqVld = Input(Vec(params.numPcMemReadPort, Bool()))
68  val fromDataPathFtqPtr = Input(Vec(params.numPcMemReadPort, new FtqPtr))
69  val fromDataPathFtqOffset = Input(Vec(params.numPcMemReadPort, UInt(log2Up(PredictWidth).W)))
70}
71
72class PcTargetMemIO()(implicit p: Parameters, params: BackendParams) extends XSBundle {
73  //input
74  val fromFrontendFtq = Flipped(new FtqToCtrlIO)
75  val fromDataPathVld = Input(Vec(params.numTargetReadPort, Bool()))
76  val fromDataPathFtq = Input(Vec(params.numTargetReadPort, new FtqPtr))
77  //output
78  val toExus = Output(Vec(params.numTargetReadPort, UInt(VAddrData().dataWidth.W)))
79  val pcToDataPath = new PcToDataPathIO(params)
80}