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