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}