xref: /XiangShan/src/main/scala/xiangshan/backend/datapath/PcTargetMem.scala (revision f533cba743d2fde15652388004e2eb36095c4b69)
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
20ce95ff3aSsinsanction  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
22ce95ff3aSsinsanction
23d8a24b06SzhanglyGit  val io = IO(new PcTargetMemIO())
24ce95ff3aSsinsanction  private val readValid = io.toDataPath.fromDataPathValid
25d8a24b06SzhanglyGit
269477429fSsinceforYy  private def hasRen: Boolean = true
27*f533cba7SHuSipeng  private val targetMem = Module(new SyncDataModuleTemplate(new Ftq_RF_Components, FtqSize, numTargetMemRead, 1, hasRen = hasRen))
28ce95ff3aSsinsanction  private val targetPCVec : Vec[UInt] = Wire(Vec(params.numTargetReadPort, UInt(VAddrData().dataWidth.W)))
29ce95ff3aSsinsanction  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)
32*f533cba7SHuSipeng  targetMem.io.waddr.head := RegEnable(io.fromFrontendFtq.pc_mem_waddr, io.fromFrontendFtq.pc_mem_wen)
33*f533cba7SHuSipeng  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
3744b06f8aSXuan Hu
385f80df32Sxiaofeibao-xjtu  for (i <- 0 until params.numTargetReadPort) {
39ce95ff3aSsinsanction    val targetPtr = io.toDataPath.fromDataPathFtqPtr(i)
40d8a24b06SzhanglyGit    // target pc stored in next entry
41ce95ff3aSsinsanction    targetMem.io.ren.get(i) := readValid(i)
42d8a24b06SzhanglyGit    targetMem.io.raddr(i) := (targetPtr + 1.U).value
4344b06f8aSXuan Hu
44*f533cba7SHuSipeng    val needNewestTarget = RegEnable(targetPtr === io.fromFrontendFtq.newest_entry_ptr, false.B, readValid(i))
45*f533cba7SHuSipeng    targetPCVec(i) := Mux(
46*f533cba7SHuSipeng      needNewestTarget,
47*f533cba7SHuSipeng      RegEnable(newestTarget, newestEn),
48*f533cba7SHuSipeng      targetMem.io.rdata(i).startAddr
49d8a24b06SzhanglyGit    )
50d8a24b06SzhanglyGit  }
51d8a24b06SzhanglyGit
52ce95ff3aSsinsanction  for (i <- 0 until params.numPcMemReadPort) {
53ce95ff3aSsinsanction    val pcAddr = io.toDataPath.fromDataPathFtqPtr(i)
54ce95ff3aSsinsanction    val offset = io.toDataPath.fromDataPathFtqOffset(i)
55ce95ff3aSsinsanction    // pc stored in this entry
56ce95ff3aSsinsanction    targetMem.io.ren.get(i + params.numTargetReadPort) := readValid(i)
57ce95ff3aSsinsanction    targetMem.io.raddr(i + params.numTargetReadPort) := pcAddr.value
58*f533cba7SHuSipeng    pcVec(i) := targetMem.io.rdata(i + params.numTargetReadPort).getPc(RegEnable(offset, readValid(i)))
59ce95ff3aSsinsanction  }
60ce95ff3aSsinsanction
61ce95ff3aSsinsanction  io.toDataPath.toDataPathTargetPC := targetPCVec
62ce95ff3aSsinsanction  io.toDataPath.toDataPathPC := pcVec
63d8a24b06SzhanglyGit}
64d8a24b06SzhanglyGit
655f80df32Sxiaofeibao-xjtuclass PcToDataPathIO(params: BackendParams)(implicit p: Parameters) extends XSBundle {
66ce95ff3aSsinsanction  //Ftq
67ce95ff3aSsinsanction  val fromDataPathValid = Input(Vec(params.numPcMemReadPort, Bool()))
685f80df32Sxiaofeibao-xjtu  val fromDataPathFtqPtr = Input(Vec(params.numPcMemReadPort, new FtqPtr))
695f80df32Sxiaofeibao-xjtu  val fromDataPathFtqOffset = Input(Vec(params.numPcMemReadPort, UInt(log2Up(PredictWidth).W)))
70ce95ff3aSsinsanction  //Target PC
71ce95ff3aSsinsanction  val toDataPathTargetPC = Output(Vec(params.numTargetReadPort, UInt(VAddrData().dataWidth.W)))
72ce95ff3aSsinsanction  //PC
73ce95ff3aSsinsanction  val toDataPathPC = Output(Vec(params.numPcMemReadPort, UInt(VAddrData().dataWidth.W)))
745f80df32Sxiaofeibao-xjtu}
755f80df32Sxiaofeibao-xjtu
76d8a24b06SzhanglyGitclass PcTargetMemIO()(implicit p: Parameters, params: BackendParams) extends XSBundle {
77ce95ff3aSsinsanction  //from frontend
78d8a24b06SzhanglyGit  val fromFrontendFtq = Flipped(new FtqToCtrlIO)
79ce95ff3aSsinsanction  //to backend
80ce95ff3aSsinsanction  val toDataPath = new PcToDataPathIO(params)
81d8a24b06SzhanglyGit}