xref: /XiangShan/src/main/scala/xiangshan/backend/datapath/PcTargetMem.scala (revision 44b06f8ac5db9678259e26d91e3c1a6c2bd972b4)
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*44b06f8aSXuan Hu  private val targetMem = Module(new SyncDataModuleTemplate(new PcTargetMemEntry, 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
31*44b06f8aSXuan Hu  private val wdata = Wire(new PcTargetMemEntry)
32*44b06f8aSXuan Hu  wdata.addr := io.fromFrontendFtq.pc_mem_wdata
33*44b06f8aSXuan Hu  wdata.flag := io.fromFrontendFtq.pc_mem_waddr.flag
34*44b06f8aSXuan Hu
355f8b6c9eSsinceforYy  targetMem.io.wen.head := GatedValidRegNext(io.fromFrontendFtq.pc_mem_wen)
36*44b06f8aSXuan Hu  targetMem.io.waddr.head := RegEnable(io.fromFrontendFtq.pc_mem_waddr.value, io.fromFrontendFtq.pc_mem_wen)
37*44b06f8aSXuan Hu  targetMem.io.wdata.head := RegEnable(wdata, io.fromFrontendFtq.pc_mem_wen)
38*44b06f8aSXuan Hu  private val rdataVec = targetMem.io.rdata
39d8a24b06SzhanglyGit
406022c595SsinceforYy  private val newestEn: Bool = io.fromFrontendFtq.newest_entry_en
41d8a24b06SzhanglyGit  private val newestTarget: UInt = io.fromFrontendFtq.newest_entry_target
42*44b06f8aSXuan Hu
43*44b06f8aSXuan Hu  // The FtqPtr is used to compare with read ptr since its arrival(T), so it needs to be holded and bypassed.
44*44b06f8aSXuan Hu  private val currentNewestFtqPtr = DataHoldBypass(io.fromFrontendFtq.newest_entry_ptr, newestEn)
45*44b06f8aSXuan Hu  // The newest target will be used at T+1, so there is no need to bypass it.
46*44b06f8aSXuan Hu  private val currentNewestTarget = RegEnable(io.fromFrontendFtq.newest_entry_target, newestEn)
47*44b06f8aSXuan Hu  private val targetReadPtrVec = 0 until params.numTargetReadPort map { i =>
48*44b06f8aSXuan Hu    RegEnable(io.toDataPath.fromDataPathFtqPtr(i), io.toDataPath.fromDataPathValid(i))
49*44b06f8aSXuan Hu  }
50*44b06f8aSXuan Hu
515f80df32Sxiaofeibao-xjtu  for (i <- 0 until params.numTargetReadPort) {
52ce95ff3aSsinsanction    val targetPtr = io.toDataPath.fromDataPathFtqPtr(i)
53d8a24b06SzhanglyGit    // target pc stored in next entry
54ce95ff3aSsinsanction    targetMem.io.ren.get(i) := readValid(i)
55d8a24b06SzhanglyGit    targetMem.io.raddr(i) := (targetPtr + 1.U).value
56*44b06f8aSXuan Hu
57*44b06f8aSXuan Hu    val hitNewestFtqPtr = RegEnable(targetPtr === currentNewestFtqPtr, false.B, readValid(i))
58*44b06f8aSXuan Hu    targetPCVec(i) := MuxCase(
59*44b06f8aSXuan Hu      default = Fill(VAddrBits, 1.U(1.W)), // use all 1s as invalid predict jump target
60*44b06f8aSXuan Hu      mapping = Seq(
61*44b06f8aSXuan Hu        hitNewestFtqPtr -> currentNewestTarget,
62*44b06f8aSXuan Hu        (rdataVec(i).flag === targetReadPtrVec(i).flag) -> rdataVec(i).addr.startAddr,
63*44b06f8aSXuan Hu      )
64d8a24b06SzhanglyGit    )
65d8a24b06SzhanglyGit  }
66d8a24b06SzhanglyGit
67ce95ff3aSsinsanction  for (i <- 0 until params.numPcMemReadPort) {
68ce95ff3aSsinsanction    val pcAddr = io.toDataPath.fromDataPathFtqPtr(i)
69ce95ff3aSsinsanction    val offset = io.toDataPath.fromDataPathFtqOffset(i)
70ce95ff3aSsinsanction    // pc stored in this entry
71ce95ff3aSsinsanction    targetMem.io.ren.get(i + params.numTargetReadPort) := readValid(i)
72ce95ff3aSsinsanction    targetMem.io.raddr(i + params.numTargetReadPort) := pcAddr.value
73*44b06f8aSXuan Hu    pcVec(i) := targetMem.io.rdata(i + params.numTargetReadPort).addr.getPc(RegEnable(offset, readValid(i)))
74ce95ff3aSsinsanction  }
75ce95ff3aSsinsanction
76ce95ff3aSsinsanction  io.toDataPath.toDataPathTargetPC := targetPCVec
77ce95ff3aSsinsanction  io.toDataPath.toDataPathPC := pcVec
78d8a24b06SzhanglyGit}
79d8a24b06SzhanglyGit
805f80df32Sxiaofeibao-xjtuclass PcToDataPathIO(params: BackendParams)(implicit p: Parameters) extends XSBundle {
81ce95ff3aSsinsanction  //Ftq
82ce95ff3aSsinsanction  val fromDataPathValid = Input(Vec(params.numPcMemReadPort, Bool()))
835f80df32Sxiaofeibao-xjtu  val fromDataPathFtqPtr = Input(Vec(params.numPcMemReadPort, new FtqPtr))
845f80df32Sxiaofeibao-xjtu  val fromDataPathFtqOffset = Input(Vec(params.numPcMemReadPort, UInt(log2Up(PredictWidth).W)))
85ce95ff3aSsinsanction  //Target PC
86ce95ff3aSsinsanction  val toDataPathTargetPC = Output(Vec(params.numTargetReadPort, UInt(VAddrData().dataWidth.W)))
87ce95ff3aSsinsanction  //PC
88ce95ff3aSsinsanction  val toDataPathPC = Output(Vec(params.numPcMemReadPort, UInt(VAddrData().dataWidth.W)))
895f80df32Sxiaofeibao-xjtu}
905f80df32Sxiaofeibao-xjtu
91d8a24b06SzhanglyGitclass PcTargetMemIO()(implicit p: Parameters, params: BackendParams) extends XSBundle {
92ce95ff3aSsinsanction  //from frontend
93d8a24b06SzhanglyGit  val fromFrontendFtq = Flipped(new FtqToCtrlIO)
94ce95ff3aSsinsanction  //to backend
95ce95ff3aSsinsanction  val toDataPath = new PcToDataPathIO(params)
96d8a24b06SzhanglyGit}
97*44b06f8aSXuan Hu
98*44b06f8aSXuan Huclass PcTargetMemEntry(implicit p: Parameters) extends XSBundle {
99*44b06f8aSXuan Hu  val addr = new Ftq_RF_Components
100*44b06f8aSXuan Hu  val flag = Bool()
101*44b06f8aSXuan Hu}
102