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 val targetMem = Module(new SyncDataModuleTemplate(new Ftq_RF_Components, FtqSize, numTargetMemRead, 1)) 24 private val jumpTargetReadVec : Vec[UInt] = Wire(Vec(params.numTargetReadPort, UInt(VAddrData().dataWidth.W))) 25 private val jumpTargetVec : Vec[UInt] = Wire(Vec(params.numTargetReadPort, UInt(VAddrData().dataWidth.W))) 26 27 targetMem.io.wen.head := RegNext(io.fromFrontendFtq.pc_mem_wen) 28 targetMem.io.waddr.head := RegEnable(io.fromFrontendFtq.pc_mem_waddr, io.fromFrontendFtq.pc_mem_wen) 29 targetMem.io.wdata.head := RegEnable(io.fromFrontendFtq.pc_mem_wdata, io.fromFrontendFtq.pc_mem_wen) 30 31 private val newestEn: Bool = io.fromFrontendFtq.newest_entry_en 32 private val newestTarget: UInt = io.fromFrontendFtq.newest_entry_target 33 for (i <- 0 until params.numTargetReadPort) { 34 val targetPtr = io.fromDataPathFtq(i) 35 // target pc stored in next entry 36 targetMem.io.raddr(i) := (targetPtr + 1.U).value 37 jumpTargetReadVec(i) := targetMem.io.rdata(i).startAddr 38 val needNewestTarget = RegNext(targetPtr === io.fromFrontendFtq.newest_entry_ptr) 39 jumpTargetVec(i) := Mux( 40 needNewestTarget, 41 RegEnable(newestTarget, newestEn), 42 jumpTargetReadVec(i) 43 ) 44 } 45 private val pcReadVec = Wire(Vec(params.numPcMemReadPort, UInt(VAddrData().dataWidth.W))) 46 private val pcVec = Wire(Vec(params.numPcMemReadPort, UInt(VAddrData().dataWidth.W))) 47 for (i <- 0 until params.numPcMemReadPort) { 48 val pcAddr = io.pcToDataPath.fromDataPathFtqPtr(i) 49 // pc stored in this entry 50 val offset = io.pcToDataPath.fromDataPathFtqOffset(i) 51 targetMem.io.raddr(i + params.numTargetReadPort) := pcAddr.value 52 pcReadVec(i) := targetMem.io.rdata(i + params.numTargetReadPort).getPc(RegNext(offset)) 53 pcVec(i) := pcReadVec(i) 54 } 55 io.pcToDataPath.toDataPathPC := pcVec 56 io.toExus := jumpTargetVec 57 58} 59 60class PcToDataPathIO(params: BackendParams)(implicit p: Parameters) extends XSBundle { 61 val toDataPathPC = Output(Vec(params.numPcMemReadPort, UInt(VAddrData().dataWidth.W))) 62 val fromDataPathFtqPtr = Input(Vec(params.numPcMemReadPort, new FtqPtr)) 63 val fromDataPathFtqOffset = Input(Vec(params.numPcMemReadPort, UInt(log2Up(PredictWidth).W))) 64} 65 66class PcTargetMemIO()(implicit p: Parameters, params: BackendParams) extends XSBundle { 67 //input 68 val fromFrontendFtq = Flipped(new FtqToCtrlIO) 69 val fromDataPathFtq = Input(Vec(params.numTargetReadPort, new FtqPtr)) 70 //output 71 val toExus = Output(Vec(params.numTargetReadPort, UInt(VAddrData().dataWidth.W))) 72 val pcToDataPath = new PcToDataPathIO(params) 73}