xref: /XiangShan/src/main/scala/xiangshan/backend/datapath/PcTargetMem.scala (revision ce95ff3ae0fe2ea2bdbe2b706c185e91c24c83c5)
1d8a24b06SzhanglyGitpackage xiangshan.backend
2d8a24b06SzhanglyGit
383ba63b3SXuan Huimport org.chipsalliance.cde.config.Parameters
4d8a24b06SzhanglyGitimport chisel3._
53827c997SsinceforYyimport chisel3.util._
6d8a24b06SzhanglyGitimport freechips.rocketchip.diplomacy.{LazyModule, LazyModuleImp}
7d8a24b06SzhanglyGitimport utility._
8d8a24b06SzhanglyGitimport xiangshan._
9d8a24b06SzhanglyGitimport xiangshan.backend.datapath.DataConfig.VAddrData
10d8a24b06SzhanglyGitimport xiangshan.frontend.{FtqPtr, FtqToCtrlIO, Ftq_RF_Components}
11d8a24b06SzhanglyGit
12d8a24b06SzhanglyGitclass PcTargetMem(params: BackendParams)(implicit p: Parameters) extends LazyModule {
131ca4a39dSXuan Hu  override def shouldBeInlined: Boolean = false
141ca4a39dSXuan Hu
15d8a24b06SzhanglyGit  lazy val module = new PcTargetMemImp(this)(p, params)
16d8a24b06SzhanglyGit}
17d8a24b06SzhanglyGit
18d8a24b06SzhanglyGitclass PcTargetMemImp(override val wrapper: PcTargetMem)(implicit p: Parameters, params: BackendParams) extends LazyModuleImp(wrapper) with HasXSParameter {
19d8a24b06SzhanglyGit
20*ce95ff3aSsinsanction  require(params.numTargetReadPort == params.numPcMemReadPort, "The EXUs which need PC must be the same as the EXUs which need Target PC.")
215f80df32Sxiaofeibao-xjtu  private val numTargetMemRead = params.numTargetReadPort + params.numPcMemReadPort
22*ce95ff3aSsinsanction
23d8a24b06SzhanglyGit  val io = IO(new PcTargetMemIO())
24*ce95ff3aSsinsanction  private val readValid = io.toDataPath.fromDataPathValid
25d8a24b06SzhanglyGit
269477429fSsinceforYy  private def hasRen: Boolean = true
279477429fSsinceforYy  private val targetMem = Module(new SyncDataModuleTemplate(new Ftq_RF_Components, FtqSize, numTargetMemRead, 1, hasRen = hasRen))
28*ce95ff3aSsinsanction  private val targetPCVec : Vec[UInt] = Wire(Vec(params.numTargetReadPort, UInt(VAddrData().dataWidth.W)))
29*ce95ff3aSsinsanction  private val pcVec       : Vec[UInt] = Wire(Vec(params.numPcMemReadPort, UInt(VAddrData().dataWidth.W)))
30d8a24b06SzhanglyGit
315f8b6c9eSsinceforYy  targetMem.io.wen.head := GatedValidRegNext(io.fromFrontendFtq.pc_mem_wen)
323827c997SsinceforYy  targetMem.io.waddr.head := RegEnable(io.fromFrontendFtq.pc_mem_waddr, io.fromFrontendFtq.pc_mem_wen)
335f80df32Sxiaofeibao-xjtu  targetMem.io.wdata.head := RegEnable(io.fromFrontendFtq.pc_mem_wdata, io.fromFrontendFtq.pc_mem_wen)
34d8a24b06SzhanglyGit
356022c595SsinceforYy  private val newestEn: Bool = io.fromFrontendFtq.newest_entry_en
36d8a24b06SzhanglyGit  private val newestTarget: UInt = io.fromFrontendFtq.newest_entry_target
375f80df32Sxiaofeibao-xjtu  for (i <- 0 until params.numTargetReadPort) {
38*ce95ff3aSsinsanction    val targetPtr = io.toDataPath.fromDataPathFtqPtr(i)
39d8a24b06SzhanglyGit    // target pc stored in next entry
40*ce95ff3aSsinsanction    targetMem.io.ren.get(i) := readValid(i)
41d8a24b06SzhanglyGit    targetMem.io.raddr(i) := (targetPtr + 1.U).value
425f8b6c9eSsinceforYy    val needNewestTarget = GatedValidRegNext(targetPtr === io.fromFrontendFtq.newest_entry_ptr)
43*ce95ff3aSsinsanction    targetPCVec(i) := Mux(
44d8a24b06SzhanglyGit      needNewestTarget,
456022c595SsinceforYy      RegEnable(newestTarget, newestEn),
46*ce95ff3aSsinsanction      targetMem.io.rdata(i).startAddr
47d8a24b06SzhanglyGit    )
48d8a24b06SzhanglyGit  }
49d8a24b06SzhanglyGit
50*ce95ff3aSsinsanction  for (i <- 0 until params.numPcMemReadPort) {
51*ce95ff3aSsinsanction    val pcAddr = io.toDataPath.fromDataPathFtqPtr(i)
52*ce95ff3aSsinsanction    val offset = io.toDataPath.fromDataPathFtqOffset(i)
53*ce95ff3aSsinsanction    // pc stored in this entry
54*ce95ff3aSsinsanction    targetMem.io.ren.get(i + params.numTargetReadPort) := readValid(i)
55*ce95ff3aSsinsanction    targetMem.io.raddr(i + params.numTargetReadPort) := pcAddr.value
56*ce95ff3aSsinsanction    pcVec(i) := targetMem.io.rdata(i + params.numTargetReadPort).getPc(RegEnable(offset, readValid(i)))
57*ce95ff3aSsinsanction  }
58*ce95ff3aSsinsanction
59*ce95ff3aSsinsanction  io.toDataPath.toDataPathTargetPC := targetPCVec
60*ce95ff3aSsinsanction  io.toDataPath.toDataPathPC := pcVec
61d8a24b06SzhanglyGit}
62d8a24b06SzhanglyGit
635f80df32Sxiaofeibao-xjtuclass PcToDataPathIO(params: BackendParams)(implicit p: Parameters) extends XSBundle {
64*ce95ff3aSsinsanction  //Ftq
65*ce95ff3aSsinsanction  val fromDataPathValid = Input(Vec(params.numPcMemReadPort, Bool()))
665f80df32Sxiaofeibao-xjtu  val fromDataPathFtqPtr = Input(Vec(params.numPcMemReadPort, new FtqPtr))
675f80df32Sxiaofeibao-xjtu  val fromDataPathFtqOffset = Input(Vec(params.numPcMemReadPort, UInt(log2Up(PredictWidth).W)))
68*ce95ff3aSsinsanction  //Target PC
69*ce95ff3aSsinsanction  val toDataPathTargetPC = Output(Vec(params.numTargetReadPort, UInt(VAddrData().dataWidth.W)))
70*ce95ff3aSsinsanction  //PC
71*ce95ff3aSsinsanction  val toDataPathPC = Output(Vec(params.numPcMemReadPort, UInt(VAddrData().dataWidth.W)))
725f80df32Sxiaofeibao-xjtu}
735f80df32Sxiaofeibao-xjtu
74d8a24b06SzhanglyGitclass PcTargetMemIO()(implicit p: Parameters, params: BackendParams) extends XSBundle {
75*ce95ff3aSsinsanction  //from frontend
76d8a24b06SzhanglyGit  val fromFrontendFtq = Flipped(new FtqToCtrlIO)
77*ce95ff3aSsinsanction  //to backend
78*ce95ff3aSsinsanction  val toDataPath = new PcToDataPathIO(params)
79d8a24b06SzhanglyGit}