1*c590fb32Scz4e/*************************************************************************************** 2*c590fb32Scz4e* Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences 3*c590fb32Scz4e* Copyright (c) 2020-2021 Peng Cheng Laboratory 4*c590fb32Scz4e* 5*c590fb32Scz4e* XiangShan is licensed under Mulan PSL v2. 6*c590fb32Scz4e* You can use this software according to the terms and conditions of the Mulan PSL v2. 7*c590fb32Scz4e* You may obtain a copy of Mulan PSL v2 at: 8*c590fb32Scz4e* http://license.coscl.org.cn/MulanPSL2 9*c590fb32Scz4e* 10*c590fb32Scz4e* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, 11*c590fb32Scz4e* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, 12*c590fb32Scz4e* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. 13*c590fb32Scz4e* 14*c590fb32Scz4e* See the Mulan PSL v2 for more details. 15*c590fb32Scz4e***************************************************************************************/ 16*c590fb32Scz4e 17*c590fb32Scz4epackage xiangshan.mem 18*c590fb32Scz4e 19*c590fb32Scz4eimport org.chipsalliance.cde.config.Parameters 20*c590fb32Scz4eimport chisel3._ 21*c590fb32Scz4eimport chisel3.util._ 22*c590fb32Scz4eimport freechips.rocketchip.diplomacy._ 23*c590fb32Scz4eimport freechips.rocketchip.diplomacy.{BundleBridgeSource, LazyModule, LazyModuleImp} 24*c590fb32Scz4eimport freechips.rocketchip.interrupts.{IntSinkNode, IntSinkPortSimple} 25*c590fb32Scz4eimport freechips.rocketchip.tile.HasFPUParameters 26*c590fb32Scz4eimport freechips.rocketchip.tilelink._ 27*c590fb32Scz4eimport device.MsiInfoBundle 28*c590fb32Scz4eimport utils._ 29*c590fb32Scz4eimport utility._ 30*c590fb32Scz4eimport system.SoCParamsKey 31*c590fb32Scz4eimport xiangshan._ 32*c590fb32Scz4eimport xiangshan.ExceptionNO._ 33*c590fb32Scz4eimport xiangshan.frontend.HasInstrMMIOConst 34*c590fb32Scz4eimport xiangshan.backend.Bundles.{DynInst, MemExuInput, MemExuOutput} 35*c590fb32Scz4eimport xiangshan.backend.ctrlblock.{DebugLSIO, LsTopdownInfo} 36*c590fb32Scz4eimport xiangshan.backend.exu.MemExeUnit 37*c590fb32Scz4eimport xiangshan.backend.fu._ 38*c590fb32Scz4eimport xiangshan.backend.fu.FuType._ 39*c590fb32Scz4eimport xiangshan.backend.fu.util.{HasCSRConst, SdtrigExt} 40*c590fb32Scz4eimport xiangshan.backend.{BackendToTopBundle, TopToBackendBundle} 41*c590fb32Scz4eimport xiangshan.backend.rob.{RobDebugRollingIO, RobPtr, RobLsqIO} 42*c590fb32Scz4eimport xiangshan.backend.datapath.NewPipelineConnect 43*c590fb32Scz4eimport xiangshan.backend.fu.NewCSR.{CsrTriggerBundle, TriggerUtil} 44*c590fb32Scz4eimport xiangshan.backend.trace.{Itype, TraceCoreInterface} 45*c590fb32Scz4eimport xiangshan.backend.Bundles._ 46*c590fb32Scz4eimport xiangshan.mem._ 47*c590fb32Scz4eimport xiangshan.mem.mdp._ 48*c590fb32Scz4eimport xiangshan.mem.prefetch.{BasePrefecher, L1Prefetcher, SMSParams, SMSPrefetcher} 49*c590fb32Scz4eimport xiangshan.cache._ 50*c590fb32Scz4eimport xiangshan.cache.mmu._ 51*c590fb32Scz4eimport coupledL2.{PrefetchRecv} 52*c590fb32Scz4e 53*c590fb32Scz4etrait HasMemBlockParameters extends HasXSParameter { 54*c590fb32Scz4e // number of memory units 55*c590fb32Scz4e val LduCnt = backendParams.LduCnt 56*c590fb32Scz4e val StaCnt = backendParams.StaCnt 57*c590fb32Scz4e val StdCnt = backendParams.StdCnt 58*c590fb32Scz4e val HyuCnt = backendParams.HyuCnt 59*c590fb32Scz4e val VlduCnt = backendParams.VlduCnt 60*c590fb32Scz4e val VstuCnt = backendParams.VstuCnt 61*c590fb32Scz4e 62*c590fb32Scz4e val LdExuCnt = LduCnt + HyuCnt 63*c590fb32Scz4e val StAddrCnt = StaCnt + HyuCnt 64*c590fb32Scz4e val StDataCnt = StdCnt 65*c590fb32Scz4e val MemExuCnt = LduCnt + HyuCnt + StaCnt + StdCnt 66*c590fb32Scz4e val MemAddrExtCnt = LdExuCnt + StaCnt 67*c590fb32Scz4e val MemVExuCnt = VlduCnt + VstuCnt 68*c590fb32Scz4e 69*c590fb32Scz4e val AtomicWBPort = 0 70*c590fb32Scz4e val MisalignWBPort = 1 71*c590fb32Scz4e val UncacheWBPort = 2 72*c590fb32Scz4e val NCWBPorts = Seq(1, 2) 73*c590fb32Scz4e} 74*c590fb32Scz4e 75*c590fb32Scz4eabstract class MemBlockBundle(implicit val p: Parameters) extends Bundle with HasMemBlockParameters 76*c590fb32Scz4e 77*c590fb32Scz4eclass Std(cfg: FuConfig)(implicit p: Parameters) extends FuncUnit(cfg) { 78*c590fb32Scz4e io.in.ready := io.out.ready 79*c590fb32Scz4e io.out.valid := io.in.valid 80*c590fb32Scz4e io.out.bits := 0.U.asTypeOf(io.out.bits) 81*c590fb32Scz4e io.out.bits.res.data := io.in.bits.data.src(0) 82*c590fb32Scz4e io.out.bits.ctrl.robIdx := io.in.bits.ctrl.robIdx 83*c590fb32Scz4e} 84*c590fb32Scz4e 85*c590fb32Scz4eclass ooo_to_mem(implicit p: Parameters) extends MemBlockBundle { 86*c590fb32Scz4e val backendToTopBypass = Flipped(new BackendToTopBundle) 87*c590fb32Scz4e 88*c590fb32Scz4e val loadFastMatch = Vec(LdExuCnt, Input(UInt(LdExuCnt.W))) 89*c590fb32Scz4e val loadFastFuOpType = Vec(LdExuCnt, Input(FuOpType())) 90*c590fb32Scz4e val loadFastImm = Vec(LdExuCnt, Input(UInt(12.W))) 91*c590fb32Scz4e val sfence = Input(new SfenceBundle) 92*c590fb32Scz4e val tlbCsr = Input(new TlbCsrBundle) 93*c590fb32Scz4e val lsqio = new Bundle { 94*c590fb32Scz4e val lcommit = Input(UInt(log2Up(CommitWidth + 1).W)) 95*c590fb32Scz4e val scommit = Input(UInt(log2Up(CommitWidth + 1).W)) 96*c590fb32Scz4e val pendingMMIOld = Input(Bool()) 97*c590fb32Scz4e val pendingld = Input(Bool()) 98*c590fb32Scz4e val pendingst = Input(Bool()) 99*c590fb32Scz4e val pendingVst = Input(Bool()) 100*c590fb32Scz4e val commit = Input(Bool()) 101*c590fb32Scz4e val pendingPtr = Input(new RobPtr) 102*c590fb32Scz4e val pendingPtrNext = Input(new RobPtr) 103*c590fb32Scz4e } 104*c590fb32Scz4e 105*c590fb32Scz4e val isStoreException = Input(Bool()) 106*c590fb32Scz4e val isVlsException = Input(Bool()) 107*c590fb32Scz4e val csrCtrl = Flipped(new CustomCSRCtrlIO) 108*c590fb32Scz4e val enqLsq = new LsqEnqIO 109*c590fb32Scz4e val flushSb = Input(Bool()) 110*c590fb32Scz4e 111*c590fb32Scz4e val storePc = Vec(StaCnt, Input(UInt(VAddrBits.W))) // for hw prefetch 112*c590fb32Scz4e val hybridPc = Vec(HyuCnt, Input(UInt(VAddrBits.W))) // for hw prefetch 113*c590fb32Scz4e 114*c590fb32Scz4e val issueLda = MixedVec(Seq.fill(LduCnt)(Flipped(DecoupledIO(new MemExuInput)))) 115*c590fb32Scz4e val issueSta = MixedVec(Seq.fill(StaCnt)(Flipped(DecoupledIO(new MemExuInput)))) 116*c590fb32Scz4e val issueStd = MixedVec(Seq.fill(StdCnt)(Flipped(DecoupledIO(new MemExuInput)))) 117*c590fb32Scz4e val issueHya = MixedVec(Seq.fill(HyuCnt)(Flipped(DecoupledIO(new MemExuInput)))) 118*c590fb32Scz4e val issueVldu = MixedVec(Seq.fill(VlduCnt)(Flipped(DecoupledIO(new MemExuInput(isVector=true))))) 119*c590fb32Scz4e 120*c590fb32Scz4e def issueUops = issueLda ++ issueSta ++ issueStd ++ issueHya ++ issueVldu 121*c590fb32Scz4e} 122*c590fb32Scz4e 123*c590fb32Scz4eclass mem_to_ooo(implicit p: Parameters) extends MemBlockBundle { 124*c590fb32Scz4e val topToBackendBypass = new TopToBackendBundle 125*c590fb32Scz4e 126*c590fb32Scz4e val otherFastWakeup = Vec(LdExuCnt, ValidIO(new DynInst)) 127*c590fb32Scz4e val lqCancelCnt = Output(UInt(log2Up(VirtualLoadQueueSize + 1).W)) 128*c590fb32Scz4e val sqCancelCnt = Output(UInt(log2Up(StoreQueueSize + 1).W)) 129*c590fb32Scz4e val sqDeq = Output(UInt(log2Ceil(EnsbufferWidth + 1).W)) 130*c590fb32Scz4e val lqDeq = Output(UInt(log2Up(CommitWidth + 1).W)) 131*c590fb32Scz4e // used by VLSU issue queue, the vector store would wait all store before it, and the vector load would wait all load 132*c590fb32Scz4e val sqDeqPtr = Output(new SqPtr) 133*c590fb32Scz4e val lqDeqPtr = Output(new LqPtr) 134*c590fb32Scz4e val stIn = Vec(StAddrCnt, ValidIO(new MemExuInput)) 135*c590fb32Scz4e val stIssuePtr = Output(new SqPtr()) 136*c590fb32Scz4e 137*c590fb32Scz4e val memoryViolation = ValidIO(new Redirect) 138*c590fb32Scz4e val sbIsEmpty = Output(Bool()) 139*c590fb32Scz4e 140*c590fb32Scz4e val lsTopdownInfo = Vec(LdExuCnt, Output(new LsTopdownInfo)) 141*c590fb32Scz4e 142*c590fb32Scz4e val lsqio = new Bundle { 143*c590fb32Scz4e val vaddr = Output(UInt(XLEN.W)) 144*c590fb32Scz4e val vstart = Output(UInt((log2Up(VLEN) + 1).W)) 145*c590fb32Scz4e val vl = Output(UInt((log2Up(VLEN) + 1).W)) 146*c590fb32Scz4e val gpaddr = Output(UInt(XLEN.W)) 147*c590fb32Scz4e val isForVSnonLeafPTE = Output(Bool()) 148*c590fb32Scz4e val mmio = Output(Vec(LoadPipelineWidth, Bool())) 149*c590fb32Scz4e val uop = Output(Vec(LoadPipelineWidth, new DynInst)) 150*c590fb32Scz4e val lqCanAccept = Output(Bool()) 151*c590fb32Scz4e val sqCanAccept = Output(Bool()) 152*c590fb32Scz4e } 153*c590fb32Scz4e 154*c590fb32Scz4e val storeDebugInfo = Vec(EnsbufferWidth, new Bundle { 155*c590fb32Scz4e val robidx = Output(new RobPtr) 156*c590fb32Scz4e val pc = Input(UInt(VAddrBits.W)) 157*c590fb32Scz4e }) 158*c590fb32Scz4e 159*c590fb32Scz4e val writebackLda = Vec(LduCnt, DecoupledIO(new MemExuOutput)) 160*c590fb32Scz4e val writebackSta = Vec(StaCnt, DecoupledIO(new MemExuOutput)) 161*c590fb32Scz4e val writebackStd = Vec(StdCnt, DecoupledIO(new MemExuOutput)) 162*c590fb32Scz4e val writebackHyuLda = Vec(HyuCnt, DecoupledIO(new MemExuOutput)) 163*c590fb32Scz4e val writebackHyuSta = Vec(HyuCnt, DecoupledIO(new MemExuOutput)) 164*c590fb32Scz4e val writebackVldu = Vec(VlduCnt, DecoupledIO(new MemExuOutput(isVector = true))) 165*c590fb32Scz4e def writeBack: Seq[DecoupledIO[MemExuOutput]] = { 166*c590fb32Scz4e writebackSta ++ 167*c590fb32Scz4e writebackHyuLda ++ writebackHyuSta ++ 168*c590fb32Scz4e writebackLda ++ 169*c590fb32Scz4e writebackVldu ++ 170*c590fb32Scz4e writebackStd 171*c590fb32Scz4e } 172*c590fb32Scz4e 173*c590fb32Scz4e val ldaIqFeedback = Vec(LduCnt, new MemRSFeedbackIO) 174*c590fb32Scz4e val staIqFeedback = Vec(StaCnt, new MemRSFeedbackIO) 175*c590fb32Scz4e val hyuIqFeedback = Vec(HyuCnt, new MemRSFeedbackIO) 176*c590fb32Scz4e val vstuIqFeedback= Vec(VstuCnt, new MemRSFeedbackIO(isVector = true)) 177*c590fb32Scz4e val vlduIqFeedback= Vec(VlduCnt, new MemRSFeedbackIO(isVector = true)) 178*c590fb32Scz4e val ldCancel = Vec(backendParams.LdExuCnt, new LoadCancelIO) 179*c590fb32Scz4e val wakeup = Vec(backendParams.LdExuCnt, Valid(new DynInst)) 180*c590fb32Scz4e 181*c590fb32Scz4e val s3_delayed_load_error = Vec(LdExuCnt, Output(Bool())) 182*c590fb32Scz4e} 183*c590fb32Scz4e 184*c590fb32Scz4eclass MemCoreTopDownIO extends Bundle { 185*c590fb32Scz4e val robHeadMissInDCache = Output(Bool()) 186*c590fb32Scz4e val robHeadTlbReplay = Output(Bool()) 187*c590fb32Scz4e val robHeadTlbMiss = Output(Bool()) 188*c590fb32Scz4e val robHeadLoadVio = Output(Bool()) 189*c590fb32Scz4e val robHeadLoadMSHR = Output(Bool()) 190*c590fb32Scz4e} 191*c590fb32Scz4e 192*c590fb32Scz4eclass fetch_to_mem(implicit p: Parameters) extends XSBundle{ 193*c590fb32Scz4e val itlb = Flipped(new TlbPtwIO()) 194*c590fb32Scz4e} 195*c590fb32Scz4e 196*c590fb32Scz4e// triple buffer applied in i-mmio path (two at MemBlock, one at L2Top) 197*c590fb32Scz4eclass InstrUncacheBuffer()(implicit p: Parameters) extends LazyModule with HasInstrMMIOConst { 198*c590fb32Scz4e val node = new TLBufferNode(BufferParams.default, BufferParams.default, BufferParams.default, BufferParams.default, BufferParams.default) 199*c590fb32Scz4e lazy val module = new InstrUncacheBufferImpl 200*c590fb32Scz4e 201*c590fb32Scz4e class InstrUncacheBufferImpl extends LazyModuleImp(this) { 202*c590fb32Scz4e (node.in zip node.out) foreach { case ((in, edgeIn), (out, edgeOut)) => 203*c590fb32Scz4e out.a <> BufferParams.default(BufferParams.default(in.a)) 204*c590fb32Scz4e in.d <> BufferParams.default(BufferParams.default(out.d)) 205*c590fb32Scz4e 206*c590fb32Scz4e // only a.valid, a.ready, a.address can change 207*c590fb32Scz4e // hoping that the rest would be optimized to keep MemBlock port unchanged after adding buffer 208*c590fb32Scz4e out.a.bits.data := 0.U 209*c590fb32Scz4e out.a.bits.mask := Fill(mmioBusBytes, 1.U(1.W)) 210*c590fb32Scz4e out.a.bits.opcode := 4.U // Get 211*c590fb32Scz4e out.a.bits.size := log2Ceil(mmioBusBytes).U 212*c590fb32Scz4e out.a.bits.source := 0.U 213*c590fb32Scz4e } 214*c590fb32Scz4e } 215*c590fb32Scz4e} 216*c590fb32Scz4e 217*c590fb32Scz4e// triple buffer applied in L1I$-L2 path (two at MemBlock, one at L2Top) 218*c590fb32Scz4eclass ICacheBuffer()(implicit p: Parameters) extends LazyModule { 219*c590fb32Scz4e val node = new TLBufferNode(BufferParams.default, BufferParams.default, BufferParams.default, BufferParams.default, BufferParams.default) 220*c590fb32Scz4e lazy val module = new ICacheBufferImpl 221*c590fb32Scz4e 222*c590fb32Scz4e class ICacheBufferImpl extends LazyModuleImp(this) { 223*c590fb32Scz4e (node.in zip node.out) foreach { case ((in, edgeIn), (out, edgeOut)) => 224*c590fb32Scz4e out.a <> BufferParams.default(BufferParams.default(in.a)) 225*c590fb32Scz4e in.d <> BufferParams.default(BufferParams.default(out.d)) 226*c590fb32Scz4e } 227*c590fb32Scz4e } 228*c590fb32Scz4e} 229*c590fb32Scz4e 230*c590fb32Scz4eclass ICacheCtrlBuffer()(implicit p: Parameters) extends LazyModule { 231*c590fb32Scz4e val node = new TLBufferNode(BufferParams.default, BufferParams.default, BufferParams.default, BufferParams.default, BufferParams.default) 232*c590fb32Scz4e lazy val module = new ICacheCtrlBufferImpl 233*c590fb32Scz4e 234*c590fb32Scz4e class ICacheCtrlBufferImpl extends LazyModuleImp(this) { 235*c590fb32Scz4e (node.in zip node.out) foreach { case ((in, edgeIn), (out, edgeOut)) => 236*c590fb32Scz4e out.a <> BufferParams.default(BufferParams.default(in.a)) 237*c590fb32Scz4e in.d <> BufferParams.default(BufferParams.default(out.d)) 238*c590fb32Scz4e } 239*c590fb32Scz4e } 240*c590fb32Scz4e} 241*c590fb32Scz4e 242*c590fb32Scz4e// Frontend bus goes through MemBlock 243*c590fb32Scz4eclass FrontendBridge()(implicit p: Parameters) extends LazyModule { 244*c590fb32Scz4e val icache_node = LazyModule(new ICacheBuffer()).suggestName("icache").node// to keep IO port name 245*c590fb32Scz4e val icachectrl_node = LazyModule(new ICacheCtrlBuffer()).suggestName("icachectrl").node 246*c590fb32Scz4e val instr_uncache_node = LazyModule(new InstrUncacheBuffer()).suggestName("instr_uncache").node 247*c590fb32Scz4e lazy val module = new LazyModuleImp(this) { 248*c590fb32Scz4e } 249*c590fb32Scz4e} 250*c590fb32Scz4e 251*c590fb32Scz4eclass MemBlockInlined()(implicit p: Parameters) extends LazyModule 252*c590fb32Scz4e with HasXSParameter { 253*c590fb32Scz4e override def shouldBeInlined: Boolean = true 254*c590fb32Scz4e 255*c590fb32Scz4e val dcache = LazyModule(new DCacheWrapper()) 256*c590fb32Scz4e val uncache = LazyModule(new Uncache()) 257*c590fb32Scz4e val uncache_port = TLTempNode() 258*c590fb32Scz4e val uncache_xbar = TLXbar() 259*c590fb32Scz4e val ptw = LazyModule(new L2TLBWrapper()) 260*c590fb32Scz4e val ptw_to_l2_buffer = if (!coreParams.softPTW) LazyModule(new TLBuffer) else null 261*c590fb32Scz4e val l1d_to_l2_buffer = if (coreParams.dcacheParametersOpt.nonEmpty) LazyModule(new TLBuffer) else null 262*c590fb32Scz4e val dcache_port = TLNameNode("dcache_client") // to keep dcache-L2 port name 263*c590fb32Scz4e val l2_pf_sender_opt = coreParams.prefetcher.map(_ => 264*c590fb32Scz4e BundleBridgeSource(() => new PrefetchRecv) 265*c590fb32Scz4e ) 266*c590fb32Scz4e val l3_pf_sender_opt = if (p(SoCParamsKey).L3CacheParamsOpt.nonEmpty) coreParams.prefetcher.map(_ => 267*c590fb32Scz4e BundleBridgeSource(() => new huancun.PrefetchRecv) 268*c590fb32Scz4e ) else None 269*c590fb32Scz4e val frontendBridge = LazyModule(new FrontendBridge) 270*c590fb32Scz4e // interrupt sinks 271*c590fb32Scz4e val clint_int_sink = IntSinkNode(IntSinkPortSimple(1, 2)) 272*c590fb32Scz4e val debug_int_sink = IntSinkNode(IntSinkPortSimple(1, 1)) 273*c590fb32Scz4e val plic_int_sink = IntSinkNode(IntSinkPortSimple(2, 1)) 274*c590fb32Scz4e val nmi_int_sink = IntSinkNode(IntSinkPortSimple(1, (new NonmaskableInterruptIO).elements.size)) 275*c590fb32Scz4e 276*c590fb32Scz4e if (!coreParams.softPTW) { 277*c590fb32Scz4e ptw_to_l2_buffer.node := ptw.node 278*c590fb32Scz4e } 279*c590fb32Scz4e uncache_xbar := TLBuffer() := uncache.clientNode 280*c590fb32Scz4e if (dcache.uncacheNode.isDefined) { 281*c590fb32Scz4e dcache.uncacheNode.get := TLBuffer.chainNode(2) := uncache_xbar 282*c590fb32Scz4e } 283*c590fb32Scz4e uncache_port := TLBuffer.chainNode(2) := uncache_xbar 284*c590fb32Scz4e 285*c590fb32Scz4e lazy val module = new MemBlockInlinedImp(this) 286*c590fb32Scz4e} 287*c590fb32Scz4e 288*c590fb32Scz4eclass MemBlockInlinedImp(outer: MemBlockInlined) extends LazyModuleImp(outer) 289*c590fb32Scz4e with HasXSParameter 290*c590fb32Scz4e with HasFPUParameters 291*c590fb32Scz4e with HasPerfEvents 292*c590fb32Scz4e with HasL1PrefetchSourceParameter 293*c590fb32Scz4e with HasCircularQueuePtrHelper 294*c590fb32Scz4e with HasMemBlockParameters 295*c590fb32Scz4e with HasTlbConst 296*c590fb32Scz4e with HasCSRConst 297*c590fb32Scz4e with SdtrigExt 298*c590fb32Scz4e{ 299*c590fb32Scz4e val io = IO(new Bundle { 300*c590fb32Scz4e val hartId = Input(UInt(hartIdLen.W)) 301*c590fb32Scz4e val redirect = Flipped(ValidIO(new Redirect)) 302*c590fb32Scz4e 303*c590fb32Scz4e val ooo_to_mem = new ooo_to_mem 304*c590fb32Scz4e val mem_to_ooo = new mem_to_ooo 305*c590fb32Scz4e val fetch_to_mem = new fetch_to_mem 306*c590fb32Scz4e 307*c590fb32Scz4e val ifetchPrefetch = Vec(LduCnt, ValidIO(new SoftIfetchPrefetchBundle)) 308*c590fb32Scz4e 309*c590fb32Scz4e // misc 310*c590fb32Scz4e val error = ValidIO(new L1CacheErrorInfo) 311*c590fb32Scz4e val memInfo = new Bundle { 312*c590fb32Scz4e val sqFull = Output(Bool()) 313*c590fb32Scz4e val lqFull = Output(Bool()) 314*c590fb32Scz4e val dcacheMSHRFull = Output(Bool()) 315*c590fb32Scz4e } 316*c590fb32Scz4e val debug_ls = new DebugLSIO 317*c590fb32Scz4e val l2_hint = Input(Valid(new L2ToL1Hint())) 318*c590fb32Scz4e val l2PfqBusy = Input(Bool()) 319*c590fb32Scz4e val l2_tlb_req = Flipped(new TlbRequestIO(nRespDups = 2)) 320*c590fb32Scz4e val l2_pmp_resp = new PMPRespBundle 321*c590fb32Scz4e val l2_flush_done = Input(Bool()) 322*c590fb32Scz4e 323*c590fb32Scz4e val debugTopDown = new Bundle { 324*c590fb32Scz4e val robHeadVaddr = Flipped(Valid(UInt(VAddrBits.W))) 325*c590fb32Scz4e val toCore = new MemCoreTopDownIO 326*c590fb32Scz4e } 327*c590fb32Scz4e val debugRolling = Flipped(new RobDebugRollingIO) 328*c590fb32Scz4e 329*c590fb32Scz4e // All the signals from/to frontend/backend to/from bus will go through MemBlock 330*c590fb32Scz4e val fromTopToBackend = Input(new Bundle { 331*c590fb32Scz4e val msiInfo = ValidIO(new MsiInfoBundle) 332*c590fb32Scz4e val clintTime = ValidIO(UInt(64.W)) 333*c590fb32Scz4e }) 334*c590fb32Scz4e val inner_hartId = Output(UInt(hartIdLen.W)) 335*c590fb32Scz4e val inner_reset_vector = Output(UInt(PAddrBits.W)) 336*c590fb32Scz4e val outer_reset_vector = Input(UInt(PAddrBits.W)) 337*c590fb32Scz4e val outer_cpu_halt = Output(Bool()) 338*c590fb32Scz4e val outer_l2_flush_en = Output(Bool()) 339*c590fb32Scz4e val outer_power_down_en = Output(Bool()) 340*c590fb32Scz4e val outer_cpu_critical_error = Output(Bool()) 341*c590fb32Scz4e val inner_beu_errors_icache = Input(new L1BusErrorUnitInfo) 342*c590fb32Scz4e val outer_beu_errors_icache = Output(new L1BusErrorUnitInfo) 343*c590fb32Scz4e val inner_hc_perfEvents = Output(Vec(numPCntHc * coreParams.L2NBanks + 1, new PerfEvent)) 344*c590fb32Scz4e val outer_hc_perfEvents = Input(Vec(numPCntHc * coreParams.L2NBanks + 1, new PerfEvent)) 345*c590fb32Scz4e 346*c590fb32Scz4e // reset signals of frontend & backend are generated in memblock 347*c590fb32Scz4e val reset_backend = Output(Reset()) 348*c590fb32Scz4e // Reset singal from frontend. 349*c590fb32Scz4e val resetInFrontendBypass = new Bundle{ 350*c590fb32Scz4e val fromFrontend = Input(Bool()) 351*c590fb32Scz4e val toL2Top = Output(Bool()) 352*c590fb32Scz4e } 353*c590fb32Scz4e val traceCoreInterfaceBypass = new Bundle{ 354*c590fb32Scz4e val fromBackend = Flipped(new TraceCoreInterface(hasOffset = true)) 355*c590fb32Scz4e val toL2Top = new TraceCoreInterface 356*c590fb32Scz4e } 357*c590fb32Scz4e 358*c590fb32Scz4e val topDownInfo = new Bundle { 359*c590fb32Scz4e val fromL2Top = Input(new TopDownFromL2Top) 360*c590fb32Scz4e val toBackend = Flipped(new TopDownInfo) 361*c590fb32Scz4e } 362*c590fb32Scz4e }) 363*c590fb32Scz4e 364*c590fb32Scz4e dontTouch(io.inner_hartId) 365*c590fb32Scz4e dontTouch(io.inner_reset_vector) 366*c590fb32Scz4e dontTouch(io.outer_reset_vector) 367*c590fb32Scz4e dontTouch(io.outer_cpu_halt) 368*c590fb32Scz4e dontTouch(io.outer_l2_flush_en) 369*c590fb32Scz4e dontTouch(io.outer_power_down_en) 370*c590fb32Scz4e dontTouch(io.outer_cpu_critical_error) 371*c590fb32Scz4e dontTouch(io.inner_beu_errors_icache) 372*c590fb32Scz4e dontTouch(io.outer_beu_errors_icache) 373*c590fb32Scz4e dontTouch(io.inner_hc_perfEvents) 374*c590fb32Scz4e dontTouch(io.outer_hc_perfEvents) 375*c590fb32Scz4e 376*c590fb32Scz4e val redirect = RegNextWithEnable(io.redirect) 377*c590fb32Scz4e 378*c590fb32Scz4e private val dcache = outer.dcache.module 379*c590fb32Scz4e val uncache = outer.uncache.module 380*c590fb32Scz4e 381*c590fb32Scz4e //val delayedDcacheRefill = RegNext(dcache.io.lsu.lsq) 382*c590fb32Scz4e 383*c590fb32Scz4e val csrCtrl = DelayN(io.ooo_to_mem.csrCtrl, 2) 384*c590fb32Scz4e dcache.io.l2_pf_store_only := RegNext(io.ooo_to_mem.csrCtrl.pf_ctrl.l2_pf_store_only, false.B) 385*c590fb32Scz4e io.error <> DelayNWithValid(dcache.io.error, 2) 386*c590fb32Scz4e when(!csrCtrl.cache_error_enable){ 387*c590fb32Scz4e io.error.bits.report_to_beu := false.B 388*c590fb32Scz4e io.error.valid := false.B 389*c590fb32Scz4e } 390*c590fb32Scz4e 391*c590fb32Scz4e val loadUnits = Seq.fill(LduCnt)(Module(new LoadUnit)) 392*c590fb32Scz4e val storeUnits = Seq.fill(StaCnt)(Module(new StoreUnit)) 393*c590fb32Scz4e val stdExeUnits = Seq.fill(StdCnt)(Module(new MemExeUnit(backendParams.memSchdParams.get.issueBlockParams.find(_.StdCnt != 0).get.exuBlockParams.head))) 394*c590fb32Scz4e val hybridUnits = Seq.fill(HyuCnt)(Module(new HybridUnit)) // Todo: replace it with HybridUnit 395*c590fb32Scz4e val stData = stdExeUnits.map(_.io.out) 396*c590fb32Scz4e val exeUnits = loadUnits ++ storeUnits 397*c590fb32Scz4e 398*c590fb32Scz4e // The number of vector load/store units is decoupled with the number of load/store units 399*c590fb32Scz4e val vlSplit = Seq.fill(VlduCnt)(Module(new VLSplitImp)) 400*c590fb32Scz4e val vsSplit = Seq.fill(VstuCnt)(Module(new VSSplitImp)) 401*c590fb32Scz4e val vlMergeBuffer = Module(new VLMergeBufferImp) 402*c590fb32Scz4e val vsMergeBuffer = Seq.fill(VstuCnt)(Module(new VSMergeBufferImp)) 403*c590fb32Scz4e val vSegmentUnit = Module(new VSegmentUnit) 404*c590fb32Scz4e val vfofBuffer = Module(new VfofBuffer) 405*c590fb32Scz4e 406*c590fb32Scz4e // misalign Buffer 407*c590fb32Scz4e val loadMisalignBuffer = Module(new LoadMisalignBuffer) 408*c590fb32Scz4e val storeMisalignBuffer = Module(new StoreMisalignBuffer) 409*c590fb32Scz4e 410*c590fb32Scz4e val l1_pf_req = Wire(Decoupled(new L1PrefetchReq())) 411*c590fb32Scz4e dcache.io.sms_agt_evict_req.ready := false.B 412*c590fb32Scz4e val prefetcherOpt: Option[BasePrefecher] = coreParams.prefetcher.map { 413*c590fb32Scz4e case _: SMSParams => 414*c590fb32Scz4e val sms = Module(new SMSPrefetcher()) 415*c590fb32Scz4e sms.io_agt_en := GatedRegNextN(io.ooo_to_mem.csrCtrl.pf_ctrl.l1D_pf_enable_agt, 2, Some(false.B)) 416*c590fb32Scz4e sms.io_pht_en := GatedRegNextN(io.ooo_to_mem.csrCtrl.pf_ctrl.l1D_pf_enable_pht, 2, Some(false.B)) 417*c590fb32Scz4e sms.io_act_threshold := GatedRegNextN(io.ooo_to_mem.csrCtrl.pf_ctrl.l1D_pf_active_threshold, 2, Some(12.U)) 418*c590fb32Scz4e sms.io_act_stride := GatedRegNextN(io.ooo_to_mem.csrCtrl.pf_ctrl.l1D_pf_active_stride, 2, Some(30.U)) 419*c590fb32Scz4e sms.io_stride_en := false.B 420*c590fb32Scz4e sms.io_dcache_evict <> dcache.io.sms_agt_evict_req 421*c590fb32Scz4e sms 422*c590fb32Scz4e } 423*c590fb32Scz4e prefetcherOpt.foreach{ pf => pf.io.l1_req.ready := false.B } 424*c590fb32Scz4e val hartId = p(XSCoreParamsKey).HartId 425*c590fb32Scz4e val l1PrefetcherOpt: Option[BasePrefecher] = coreParams.prefetcher.map { 426*c590fb32Scz4e case _ => 427*c590fb32Scz4e val l1Prefetcher = Module(new L1Prefetcher()) 428*c590fb32Scz4e l1Prefetcher.io.enable := Constantin.createRecord(s"enableL1StreamPrefetcher$hartId", initValue = true) 429*c590fb32Scz4e l1Prefetcher.pf_ctrl <> dcache.io.pf_ctrl 430*c590fb32Scz4e l1Prefetcher.l2PfqBusy := io.l2PfqBusy 431*c590fb32Scz4e 432*c590fb32Scz4e // stride will train on miss or prefetch hit 433*c590fb32Scz4e for (i <- 0 until LduCnt) { 434*c590fb32Scz4e val source = loadUnits(i).io.prefetch_train_l1 435*c590fb32Scz4e l1Prefetcher.stride_train(i).valid := source.valid && source.bits.isFirstIssue && ( 436*c590fb32Scz4e source.bits.miss || isFromStride(source.bits.meta_prefetch) 437*c590fb32Scz4e ) 438*c590fb32Scz4e l1Prefetcher.stride_train(i).bits := source.bits 439*c590fb32Scz4e val loadPc = RegNext(io.ooo_to_mem.issueLda(i).bits.uop.pc) // for s1 440*c590fb32Scz4e l1Prefetcher.stride_train(i).bits.uop.pc := Mux( 441*c590fb32Scz4e loadUnits(i).io.s2_ptr_chasing, 442*c590fb32Scz4e RegEnable(loadPc, loadUnits(i).io.s2_prefetch_spec), 443*c590fb32Scz4e RegEnable(RegEnable(loadPc, loadUnits(i).io.s1_prefetch_spec), loadUnits(i).io.s2_prefetch_spec) 444*c590fb32Scz4e ) 445*c590fb32Scz4e } 446*c590fb32Scz4e for (i <- 0 until HyuCnt) { 447*c590fb32Scz4e val source = hybridUnits(i).io.prefetch_train_l1 448*c590fb32Scz4e l1Prefetcher.stride_train.drop(LduCnt)(i).valid := source.valid && source.bits.isFirstIssue && ( 449*c590fb32Scz4e source.bits.miss || isFromStride(source.bits.meta_prefetch) 450*c590fb32Scz4e ) 451*c590fb32Scz4e l1Prefetcher.stride_train.drop(LduCnt)(i).bits := source.bits 452*c590fb32Scz4e l1Prefetcher.stride_train.drop(LduCnt)(i).bits.uop.pc := Mux( 453*c590fb32Scz4e hybridUnits(i).io.ldu_io.s2_ptr_chasing, 454*c590fb32Scz4e RegNext(io.ooo_to_mem.hybridPc(i)), 455*c590fb32Scz4e RegNext(RegNext(io.ooo_to_mem.hybridPc(i))) 456*c590fb32Scz4e ) 457*c590fb32Scz4e } 458*c590fb32Scz4e l1Prefetcher 459*c590fb32Scz4e } 460*c590fb32Scz4e // load prefetch to l1 Dcache 461*c590fb32Scz4e l1PrefetcherOpt match { 462*c590fb32Scz4e case Some(pf) => l1_pf_req <> Pipeline(in = pf.io.l1_req, depth = 1, pipe = false, name = Some("pf_queue_to_ldu_reg")) 463*c590fb32Scz4e case None => 464*c590fb32Scz4e l1_pf_req.valid := false.B 465*c590fb32Scz4e l1_pf_req.bits := DontCare 466*c590fb32Scz4e } 467*c590fb32Scz4e val pf_train_on_hit = RegNextN(io.ooo_to_mem.csrCtrl.pf_ctrl.l1D_pf_train_on_hit, 2, Some(true.B)) 468*c590fb32Scz4e 469*c590fb32Scz4e loadUnits.zipWithIndex.map(x => x._1.suggestName("LoadUnit_"+x._2)) 470*c590fb32Scz4e storeUnits.zipWithIndex.map(x => x._1.suggestName("StoreUnit_"+x._2)) 471*c590fb32Scz4e hybridUnits.zipWithIndex.map(x => x._1.suggestName("HybridUnit_"+x._2)) 472*c590fb32Scz4e val atomicsUnit = Module(new AtomicsUnit) 473*c590fb32Scz4e 474*c590fb32Scz4e 475*c590fb32Scz4e val ldaExeWbReqs = Wire(Vec(LduCnt, Decoupled(new MemExuOutput))) 476*c590fb32Scz4e // atomicsUnit will overwrite the source from ldu if it is about to writeback 477*c590fb32Scz4e val atomicWritebackOverride = Mux( 478*c590fb32Scz4e atomicsUnit.io.out.valid, 479*c590fb32Scz4e atomicsUnit.io.out.bits, 480*c590fb32Scz4e loadUnits(AtomicWBPort).io.ldout.bits 481*c590fb32Scz4e ) 482*c590fb32Scz4e ldaExeWbReqs(AtomicWBPort).valid := atomicsUnit.io.out.valid || loadUnits(AtomicWBPort).io.ldout.valid 483*c590fb32Scz4e ldaExeWbReqs(AtomicWBPort).bits := atomicWritebackOverride 484*c590fb32Scz4e atomicsUnit.io.out.ready := ldaExeWbReqs(AtomicWBPort).ready 485*c590fb32Scz4e loadUnits(AtomicWBPort).io.ldout.ready := ldaExeWbReqs(AtomicWBPort).ready 486*c590fb32Scz4e 487*c590fb32Scz4e val st_data_atomics = Seq.tabulate(StdCnt)(i => 488*c590fb32Scz4e stData(i).valid && FuType.storeIsAMO(stData(i).bits.uop.fuType) 489*c590fb32Scz4e ) 490*c590fb32Scz4e 491*c590fb32Scz4e // misalignBuffer will overwrite the source from ldu if it is about to writeback 492*c590fb32Scz4e val misalignWritebackOverride = Mux( 493*c590fb32Scz4e loadUnits(MisalignWBPort).io.ldout.valid, 494*c590fb32Scz4e loadUnits(MisalignWBPort).io.ldout.bits, 495*c590fb32Scz4e loadMisalignBuffer.io.writeBack.bits 496*c590fb32Scz4e ) 497*c590fb32Scz4e ldaExeWbReqs(MisalignWBPort).valid := loadMisalignBuffer.io.writeBack.valid || loadUnits(MisalignWBPort).io.ldout.valid 498*c590fb32Scz4e ldaExeWbReqs(MisalignWBPort).bits := misalignWritebackOverride 499*c590fb32Scz4e loadMisalignBuffer.io.writeBack.ready := ldaExeWbReqs(MisalignWBPort).ready && !loadUnits(MisalignWBPort).io.ldout.valid 500*c590fb32Scz4e loadMisalignBuffer.io.loadOutValid := loadUnits(MisalignWBPort).io.ldout.valid 501*c590fb32Scz4e loadMisalignBuffer.io.loadVecOutValid := loadUnits(MisalignWBPort).io.vecldout.valid 502*c590fb32Scz4e loadUnits(MisalignWBPort).io.ldout.ready := ldaExeWbReqs(MisalignWBPort).ready 503*c590fb32Scz4e ldaExeWbReqs(MisalignWBPort).bits.isFromLoadUnit := loadUnits(MisalignWBPort).io.ldout.bits.isFromLoadUnit || loadMisalignBuffer.io.writeBack.valid 504*c590fb32Scz4e 505*c590fb32Scz4e // loadUnit will overwrite the source from uncache if it is about to writeback 506*c590fb32Scz4e ldaExeWbReqs(UncacheWBPort) <> loadUnits(UncacheWBPort).io.ldout 507*c590fb32Scz4e io.mem_to_ooo.writebackLda <> ldaExeWbReqs 508*c590fb32Scz4e io.mem_to_ooo.writebackSta <> storeUnits.map(_.io.stout) 509*c590fb32Scz4e io.mem_to_ooo.writebackStd.zip(stdExeUnits).foreach {x => 510*c590fb32Scz4e x._1.bits := x._2.io.out.bits 511*c590fb32Scz4e // AMOs do not need to write back std now. 512*c590fb32Scz4e x._1.valid := x._2.io.out.fire && !FuType.storeIsAMO(x._2.io.out.bits.uop.fuType) 513*c590fb32Scz4e } 514*c590fb32Scz4e io.mem_to_ooo.writebackHyuLda <> hybridUnits.map(_.io.ldout) 515*c590fb32Scz4e io.mem_to_ooo.writebackHyuSta <> hybridUnits.map(_.io.stout) 516*c590fb32Scz4e io.mem_to_ooo.otherFastWakeup := DontCare 517*c590fb32Scz4e io.mem_to_ooo.otherFastWakeup.drop(HyuCnt).take(LduCnt).zip(loadUnits.map(_.io.fast_uop)).foreach{case(a,b)=> a := b} 518*c590fb32Scz4e io.mem_to_ooo.otherFastWakeup.take(HyuCnt).zip(hybridUnits.map(_.io.ldu_io.fast_uop)).foreach{case(a,b)=> a:=b} 519*c590fb32Scz4e val stOut = io.mem_to_ooo.writebackSta ++ io.mem_to_ooo.writebackHyuSta 520*c590fb32Scz4e 521*c590fb32Scz4e // prefetch to l1 req 522*c590fb32Scz4e // Stream's confidence is always 1 523*c590fb32Scz4e // (LduCnt + HyuCnt) l1_pf_reqs ? 524*c590fb32Scz4e loadUnits.foreach(load_unit => { 525*c590fb32Scz4e load_unit.io.prefetch_req.valid <> l1_pf_req.valid 526*c590fb32Scz4e load_unit.io.prefetch_req.bits <> l1_pf_req.bits 527*c590fb32Scz4e }) 528*c590fb32Scz4e 529*c590fb32Scz4e hybridUnits.foreach(hybrid_unit => { 530*c590fb32Scz4e hybrid_unit.io.ldu_io.prefetch_req.valid <> l1_pf_req.valid 531*c590fb32Scz4e hybrid_unit.io.ldu_io.prefetch_req.bits <> l1_pf_req.bits 532*c590fb32Scz4e }) 533*c590fb32Scz4e 534*c590fb32Scz4e // NOTE: loadUnits(0) has higher bank conflict and miss queue arb priority than loadUnits(1) and loadUnits(2) 535*c590fb32Scz4e // when loadUnits(1)/loadUnits(2) stage 0 is busy, hw prefetch will never use that pipeline 536*c590fb32Scz4e val LowConfPorts = if (LduCnt == 2) Seq(1) else if (LduCnt == 3) Seq(1, 2) else Seq(0) 537*c590fb32Scz4e LowConfPorts.map{case i => loadUnits(i).io.prefetch_req.bits.confidence := 0.U} 538*c590fb32Scz4e hybridUnits.foreach(hybrid_unit => { hybrid_unit.io.ldu_io.prefetch_req.bits.confidence := 0.U }) 539*c590fb32Scz4e 540*c590fb32Scz4e val canAcceptHighConfPrefetch = loadUnits.map(_.io.canAcceptHighConfPrefetch) ++ 541*c590fb32Scz4e hybridUnits.map(_.io.canAcceptLowConfPrefetch) 542*c590fb32Scz4e val canAcceptLowConfPrefetch = loadUnits.map(_.io.canAcceptLowConfPrefetch) ++ 543*c590fb32Scz4e hybridUnits.map(_.io.canAcceptLowConfPrefetch) 544*c590fb32Scz4e l1_pf_req.ready := (0 until LduCnt + HyuCnt).map{ 545*c590fb32Scz4e case i => { 546*c590fb32Scz4e if (LowConfPorts.contains(i)) { 547*c590fb32Scz4e loadUnits(i).io.canAcceptLowConfPrefetch 548*c590fb32Scz4e } else { 549*c590fb32Scz4e Mux(l1_pf_req.bits.confidence === 1.U, canAcceptHighConfPrefetch(i), canAcceptLowConfPrefetch(i)) 550*c590fb32Scz4e } 551*c590fb32Scz4e } 552*c590fb32Scz4e }.reduce(_ || _) 553*c590fb32Scz4e 554*c590fb32Scz4e // l1 pf fuzzer interface 555*c590fb32Scz4e val DebugEnableL1PFFuzzer = false 556*c590fb32Scz4e if (DebugEnableL1PFFuzzer) { 557*c590fb32Scz4e // l1 pf req fuzzer 558*c590fb32Scz4e val fuzzer = Module(new L1PrefetchFuzzer()) 559*c590fb32Scz4e fuzzer.io.vaddr := DontCare 560*c590fb32Scz4e fuzzer.io.paddr := DontCare 561*c590fb32Scz4e 562*c590fb32Scz4e // override load_unit prefetch_req 563*c590fb32Scz4e loadUnits.foreach(load_unit => { 564*c590fb32Scz4e load_unit.io.prefetch_req.valid <> fuzzer.io.req.valid 565*c590fb32Scz4e load_unit.io.prefetch_req.bits <> fuzzer.io.req.bits 566*c590fb32Scz4e }) 567*c590fb32Scz4e 568*c590fb32Scz4e // override hybrid_unit prefetch_req 569*c590fb32Scz4e hybridUnits.foreach(hybrid_unit => { 570*c590fb32Scz4e hybrid_unit.io.ldu_io.prefetch_req.valid <> fuzzer.io.req.valid 571*c590fb32Scz4e hybrid_unit.io.ldu_io.prefetch_req.bits <> fuzzer.io.req.bits 572*c590fb32Scz4e }) 573*c590fb32Scz4e 574*c590fb32Scz4e fuzzer.io.req.ready := l1_pf_req.ready 575*c590fb32Scz4e } 576*c590fb32Scz4e 577*c590fb32Scz4e // TODO: fast load wakeup 578*c590fb32Scz4e val lsq = Module(new LsqWrapper) 579*c590fb32Scz4e val sbuffer = Module(new Sbuffer) 580*c590fb32Scz4e // if you wants to stress test dcache store, use FakeSbuffer 581*c590fb32Scz4e // val sbuffer = Module(new FakeSbuffer) // out of date now 582*c590fb32Scz4e io.mem_to_ooo.stIssuePtr := lsq.io.issuePtrExt 583*c590fb32Scz4e 584*c590fb32Scz4e dcache.io.hartId := io.hartId 585*c590fb32Scz4e lsq.io.hartId := io.hartId 586*c590fb32Scz4e sbuffer.io.hartId := io.hartId 587*c590fb32Scz4e atomicsUnit.io.hartId := io.hartId 588*c590fb32Scz4e 589*c590fb32Scz4e dcache.io.lqEmpty := lsq.io.lqEmpty 590*c590fb32Scz4e 591*c590fb32Scz4e // load/store prefetch to l2 cache 592*c590fb32Scz4e prefetcherOpt.foreach(sms_pf => { 593*c590fb32Scz4e l1PrefetcherOpt.foreach(l1_pf => { 594*c590fb32Scz4e val sms_pf_to_l2 = DelayNWithValid(sms_pf.io.l2_req, 2) 595*c590fb32Scz4e val l1_pf_to_l2 = DelayNWithValid(l1_pf.io.l2_req, 2) 596*c590fb32Scz4e 597*c590fb32Scz4e outer.l2_pf_sender_opt.get.out.head._1.addr_valid := sms_pf_to_l2.valid || l1_pf_to_l2.valid 598*c590fb32Scz4e outer.l2_pf_sender_opt.get.out.head._1.addr := Mux(l1_pf_to_l2.valid, l1_pf_to_l2.bits.addr, sms_pf_to_l2.bits.addr) 599*c590fb32Scz4e outer.l2_pf_sender_opt.get.out.head._1.pf_source := Mux(l1_pf_to_l2.valid, l1_pf_to_l2.bits.source, sms_pf_to_l2.bits.source) 600*c590fb32Scz4e outer.l2_pf_sender_opt.get.out.head._1.l2_pf_en := RegNextN(io.ooo_to_mem.csrCtrl.pf_ctrl.l2_pf_enable, 2, Some(true.B)) 601*c590fb32Scz4e 602*c590fb32Scz4e sms_pf.io.enable := RegNextN(io.ooo_to_mem.csrCtrl.pf_ctrl.l1D_pf_enable, 2, Some(false.B)) 603*c590fb32Scz4e 604*c590fb32Scz4e val l2_trace = Wire(new LoadPfDbBundle) 605*c590fb32Scz4e l2_trace.paddr := outer.l2_pf_sender_opt.get.out.head._1.addr 606*c590fb32Scz4e val table = ChiselDB.createTable(s"L2PrefetchTrace$hartId", new LoadPfDbBundle, basicDB = false) 607*c590fb32Scz4e table.log(l2_trace, l1_pf_to_l2.valid, "StreamPrefetchTrace", clock, reset) 608*c590fb32Scz4e table.log(l2_trace, !l1_pf_to_l2.valid && sms_pf_to_l2.valid, "L2PrefetchTrace", clock, reset) 609*c590fb32Scz4e 610*c590fb32Scz4e val l1_pf_to_l3 = ValidIODelay(l1_pf.io.l3_req, 4) 611*c590fb32Scz4e outer.l3_pf_sender_opt.foreach(_.out.head._1.addr_valid := l1_pf_to_l3.valid) 612*c590fb32Scz4e outer.l3_pf_sender_opt.foreach(_.out.head._1.addr := l1_pf_to_l3.bits) 613*c590fb32Scz4e outer.l3_pf_sender_opt.foreach(_.out.head._1.l2_pf_en := RegNextN(io.ooo_to_mem.csrCtrl.pf_ctrl.l2_pf_enable, 4, Some(true.B))) 614*c590fb32Scz4e 615*c590fb32Scz4e val l3_trace = Wire(new LoadPfDbBundle) 616*c590fb32Scz4e l3_trace.paddr := outer.l3_pf_sender_opt.map(_.out.head._1.addr).getOrElse(0.U) 617*c590fb32Scz4e val l3_table = ChiselDB.createTable(s"L3PrefetchTrace$hartId", new LoadPfDbBundle, basicDB = false) 618*c590fb32Scz4e l3_table.log(l3_trace, l1_pf_to_l3.valid, "StreamPrefetchTrace", clock, reset) 619*c590fb32Scz4e 620*c590fb32Scz4e XSPerfAccumulate("prefetch_fire_l2", outer.l2_pf_sender_opt.get.out.head._1.addr_valid) 621*c590fb32Scz4e XSPerfAccumulate("prefetch_fire_l3", outer.l3_pf_sender_opt.map(_.out.head._1.addr_valid).getOrElse(false.B)) 622*c590fb32Scz4e XSPerfAccumulate("l1pf_fire_l2", l1_pf_to_l2.valid) 623*c590fb32Scz4e XSPerfAccumulate("sms_fire_l2", !l1_pf_to_l2.valid && sms_pf_to_l2.valid) 624*c590fb32Scz4e XSPerfAccumulate("sms_block_by_l1pf", l1_pf_to_l2.valid && sms_pf_to_l2.valid) 625*c590fb32Scz4e }) 626*c590fb32Scz4e }) 627*c590fb32Scz4e 628*c590fb32Scz4e // ptw 629*c590fb32Scz4e val sfence = RegNext(RegNext(io.ooo_to_mem.sfence)) 630*c590fb32Scz4e val tlbcsr = RegNext(RegNext(io.ooo_to_mem.tlbCsr)) 631*c590fb32Scz4e private val ptw = outer.ptw.module 632*c590fb32Scz4e private val ptw_to_l2_buffer = outer.ptw_to_l2_buffer.module 633*c590fb32Scz4e private val l1d_to_l2_buffer = outer.l1d_to_l2_buffer.module 634*c590fb32Scz4e ptw.io.hartId := io.hartId 635*c590fb32Scz4e ptw.io.sfence <> sfence 636*c590fb32Scz4e ptw.io.csr.tlb <> tlbcsr 637*c590fb32Scz4e ptw.io.csr.distribute_csr <> csrCtrl.distribute_csr 638*c590fb32Scz4e 639*c590fb32Scz4e val perfEventsPTW = if (!coreParams.softPTW) { 640*c590fb32Scz4e ptw.getPerfEvents 641*c590fb32Scz4e } else { 642*c590fb32Scz4e Seq() 643*c590fb32Scz4e } 644*c590fb32Scz4e 645*c590fb32Scz4e // dtlb 646*c590fb32Scz4e val dtlb_ld_tlb_ld = Module(new TLBNonBlock(LduCnt + HyuCnt + 1, 2, ldtlbParams)) 647*c590fb32Scz4e val dtlb_st_tlb_st = Module(new TLBNonBlock(StaCnt, 1, sttlbParams)) 648*c590fb32Scz4e val dtlb_prefetch_tlb_prefetch = Module(new TLBNonBlock(2, 2, pftlbParams)) 649*c590fb32Scz4e val dtlb_ld = Seq(dtlb_ld_tlb_ld.io) 650*c590fb32Scz4e val dtlb_st = Seq(dtlb_st_tlb_st.io) 651*c590fb32Scz4e val dtlb_prefetch = Seq(dtlb_prefetch_tlb_prefetch.io) 652*c590fb32Scz4e /* tlb vec && constant variable */ 653*c590fb32Scz4e val dtlb = dtlb_ld ++ dtlb_st ++ dtlb_prefetch 654*c590fb32Scz4e val (dtlb_ld_idx, dtlb_st_idx, dtlb_pf_idx) = (0, 1, 2) 655*c590fb32Scz4e val TlbSubSizeVec = Seq(LduCnt + HyuCnt + 1, StaCnt, 2) // (load + hyu + stream pf, store, sms+l2bop) 656*c590fb32Scz4e val DTlbSize = TlbSubSizeVec.sum 657*c590fb32Scz4e val TlbStartVec = TlbSubSizeVec.scanLeft(0)(_ + _).dropRight(1) 658*c590fb32Scz4e val TlbEndVec = TlbSubSizeVec.scanLeft(0)(_ + _).drop(1) 659*c590fb32Scz4e 660*c590fb32Scz4e val ptwio = Wire(new VectorTlbPtwIO(DTlbSize)) 661*c590fb32Scz4e val dtlb_reqs = dtlb.map(_.requestor).flatten 662*c590fb32Scz4e val dtlb_pmps = dtlb.map(_.pmp).flatten 663*c590fb32Scz4e dtlb.map(_.hartId := io.hartId) 664*c590fb32Scz4e dtlb.map(_.sfence := sfence) 665*c590fb32Scz4e dtlb.map(_.csr := tlbcsr) 666*c590fb32Scz4e dtlb.map(_.flushPipe.map(a => a := false.B)) // non-block doesn't need 667*c590fb32Scz4e dtlb.map(_.redirect := redirect) 668*c590fb32Scz4e if (refillBothTlb) { 669*c590fb32Scz4e require(ldtlbParams.outReplace == sttlbParams.outReplace) 670*c590fb32Scz4e require(ldtlbParams.outReplace == hytlbParams.outReplace) 671*c590fb32Scz4e require(ldtlbParams.outReplace == pftlbParams.outReplace) 672*c590fb32Scz4e require(ldtlbParams.outReplace) 673*c590fb32Scz4e 674*c590fb32Scz4e val replace = Module(new TlbReplace(DTlbSize, ldtlbParams)) 675*c590fb32Scz4e replace.io.apply_sep(dtlb_ld.map(_.replace) ++ dtlb_st.map(_.replace) ++ dtlb_prefetch.map(_.replace), ptwio.resp.bits.data.s1.entry.tag) 676*c590fb32Scz4e } else { 677*c590fb32Scz4e // TODO: there will be bugs in TlbReplace when outReplace enable, since the order of Hyu is not right. 678*c590fb32Scz4e if (ldtlbParams.outReplace) { 679*c590fb32Scz4e val replace_ld = Module(new TlbReplace(LduCnt + 1, ldtlbParams)) 680*c590fb32Scz4e replace_ld.io.apply_sep(dtlb_ld.map(_.replace), ptwio.resp.bits.data.s1.entry.tag) 681*c590fb32Scz4e } 682*c590fb32Scz4e if (hytlbParams.outReplace) { 683*c590fb32Scz4e val replace_hy = Module(new TlbReplace(HyuCnt, hytlbParams)) 684*c590fb32Scz4e replace_hy.io.apply_sep(dtlb_ld.map(_.replace), ptwio.resp.bits.data.s1.entry.tag) 685*c590fb32Scz4e } 686*c590fb32Scz4e if (sttlbParams.outReplace) { 687*c590fb32Scz4e val replace_st = Module(new TlbReplace(StaCnt, sttlbParams)) 688*c590fb32Scz4e replace_st.io.apply_sep(dtlb_st.map(_.replace), ptwio.resp.bits.data.s1.entry.tag) 689*c590fb32Scz4e } 690*c590fb32Scz4e if (pftlbParams.outReplace) { 691*c590fb32Scz4e val replace_pf = Module(new TlbReplace(2, pftlbParams)) 692*c590fb32Scz4e replace_pf.io.apply_sep(dtlb_prefetch.map(_.replace), ptwio.resp.bits.data.s1.entry.tag) 693*c590fb32Scz4e } 694*c590fb32Scz4e } 695*c590fb32Scz4e 696*c590fb32Scz4e val ptw_resp_next = RegEnable(ptwio.resp.bits, ptwio.resp.valid) 697*c590fb32Scz4e val ptw_resp_v = RegNext(ptwio.resp.valid && !(sfence.valid && tlbcsr.satp.changed && tlbcsr.vsatp.changed && tlbcsr.hgatp.changed), init = false.B) 698*c590fb32Scz4e ptwio.resp.ready := true.B 699*c590fb32Scz4e 700*c590fb32Scz4e val tlbreplay = WireInit(VecInit(Seq.fill(LdExuCnt)(false.B))) 701*c590fb32Scz4e val tlbreplay_reg = GatedValidRegNext(tlbreplay) 702*c590fb32Scz4e val dtlb_ld0_tlbreplay_reg = GatedValidRegNext(dtlb_ld(0).tlbreplay) 703*c590fb32Scz4e 704*c590fb32Scz4e if (backendParams.debugEn){ dontTouch(tlbreplay) } 705*c590fb32Scz4e 706*c590fb32Scz4e for (i <- 0 until LdExuCnt) { 707*c590fb32Scz4e tlbreplay(i) := dtlb_ld(0).ptw.req(i).valid && ptw_resp_next.vector(0) && ptw_resp_v && 708*c590fb32Scz4e ptw_resp_next.data.hit(dtlb_ld(0).ptw.req(i).bits.vpn, tlbcsr.satp.asid, tlbcsr.vsatp.asid, tlbcsr.hgatp.vmid, allType = true, ignoreAsid = true) 709*c590fb32Scz4e } 710*c590fb32Scz4e 711*c590fb32Scz4e dtlb.flatMap(a => a.ptw.req) 712*c590fb32Scz4e .zipWithIndex 713*c590fb32Scz4e .foreach{ case (tlb, i) => 714*c590fb32Scz4e tlb.ready := ptwio.req(i).ready 715*c590fb32Scz4e ptwio.req(i).bits := tlb.bits 716*c590fb32Scz4e val vector_hit = if (refillBothTlb) Cat(ptw_resp_next.vector).orR 717*c590fb32Scz4e else if (i < TlbEndVec(dtlb_ld_idx)) Cat(ptw_resp_next.vector.slice(TlbStartVec(dtlb_ld_idx), TlbEndVec(dtlb_ld_idx))).orR 718*c590fb32Scz4e else if (i < TlbEndVec(dtlb_st_idx)) Cat(ptw_resp_next.vector.slice(TlbStartVec(dtlb_st_idx), TlbEndVec(dtlb_st_idx))).orR 719*c590fb32Scz4e else Cat(ptw_resp_next.vector.slice(TlbStartVec(dtlb_pf_idx), TlbEndVec(dtlb_pf_idx))).orR 720*c590fb32Scz4e ptwio.req(i).valid := tlb.valid && !(ptw_resp_v && vector_hit && ptw_resp_next.data.hit(tlb.bits.vpn, tlbcsr.satp.asid, tlbcsr.vsatp.asid, tlbcsr.hgatp.vmid, allType = true, ignoreAsid = true)) 721*c590fb32Scz4e } 722*c590fb32Scz4e dtlb.foreach(_.ptw.resp.bits := ptw_resp_next.data) 723*c590fb32Scz4e if (refillBothTlb) { 724*c590fb32Scz4e dtlb.foreach(_.ptw.resp.valid := ptw_resp_v && Cat(ptw_resp_next.vector).orR) 725*c590fb32Scz4e } else { 726*c590fb32Scz4e dtlb_ld.foreach(_.ptw.resp.valid := ptw_resp_v && Cat(ptw_resp_next.vector.slice(TlbStartVec(dtlb_ld_idx), TlbEndVec(dtlb_ld_idx))).orR) 727*c590fb32Scz4e dtlb_st.foreach(_.ptw.resp.valid := ptw_resp_v && Cat(ptw_resp_next.vector.slice(TlbStartVec(dtlb_st_idx), TlbEndVec(dtlb_st_idx))).orR) 728*c590fb32Scz4e dtlb_prefetch.foreach(_.ptw.resp.valid := ptw_resp_v && Cat(ptw_resp_next.vector.slice(TlbStartVec(dtlb_pf_idx), TlbEndVec(dtlb_pf_idx))).orR) 729*c590fb32Scz4e } 730*c590fb32Scz4e dtlb_ld.foreach(_.ptw.resp.bits.getGpa := Cat(ptw_resp_next.getGpa.take(LduCnt + HyuCnt + 1)).orR) 731*c590fb32Scz4e dtlb_st.foreach(_.ptw.resp.bits.getGpa := Cat(ptw_resp_next.getGpa.slice(LduCnt + HyuCnt + 1, LduCnt + HyuCnt + 1 + StaCnt)).orR) 732*c590fb32Scz4e dtlb_prefetch.foreach(_.ptw.resp.bits.getGpa := Cat(ptw_resp_next.getGpa.drop(LduCnt + HyuCnt + 1 + StaCnt)).orR) 733*c590fb32Scz4e 734*c590fb32Scz4e val dtlbRepeater = PTWNewFilter(ldtlbParams.fenceDelay, ptwio, ptw.io.tlb(1), sfence, tlbcsr, l2tlbParams.dfilterSize) 735*c590fb32Scz4e val itlbRepeater3 = PTWRepeaterNB(passReady = false, itlbParams.fenceDelay, io.fetch_to_mem.itlb, ptw.io.tlb(0), sfence, tlbcsr) 736*c590fb32Scz4e 737*c590fb32Scz4e lsq.io.debugTopDown.robHeadMissInDTlb := dtlbRepeater.io.rob_head_miss_in_tlb 738*c590fb32Scz4e 739*c590fb32Scz4e // pmp 740*c590fb32Scz4e val pmp = Module(new PMP()) 741*c590fb32Scz4e pmp.io.distribute_csr <> csrCtrl.distribute_csr 742*c590fb32Scz4e 743*c590fb32Scz4e val pmp_checkers = Seq.fill(DTlbSize)(Module(new PMPChecker(4, leaveHitMux = true))) 744*c590fb32Scz4e val pmp_check = pmp_checkers.map(_.io) 745*c590fb32Scz4e for ((p,d) <- pmp_check zip dtlb_pmps) { 746*c590fb32Scz4e p.apply(tlbcsr.priv.dmode, pmp.io.pmp, pmp.io.pma, d) 747*c590fb32Scz4e require(p.req.bits.size.getWidth == d.bits.size.getWidth) 748*c590fb32Scz4e } 749*c590fb32Scz4e 750*c590fb32Scz4e for (i <- 0 until LduCnt) { 751*c590fb32Scz4e io.debug_ls.debugLsInfo(i) := loadUnits(i).io.debug_ls 752*c590fb32Scz4e } 753*c590fb32Scz4e for (i <- 0 until HyuCnt) { 754*c590fb32Scz4e io.debug_ls.debugLsInfo.drop(LduCnt)(i) := hybridUnits(i).io.ldu_io.debug_ls 755*c590fb32Scz4e } 756*c590fb32Scz4e for (i <- 0 until StaCnt) { 757*c590fb32Scz4e io.debug_ls.debugLsInfo.drop(LduCnt + HyuCnt)(i) := storeUnits(i).io.debug_ls 758*c590fb32Scz4e } 759*c590fb32Scz4e for (i <- 0 until HyuCnt) { 760*c590fb32Scz4e io.debug_ls.debugLsInfo.drop(LduCnt + HyuCnt + StaCnt)(i) := hybridUnits(i).io.stu_io.debug_ls 761*c590fb32Scz4e } 762*c590fb32Scz4e 763*c590fb32Scz4e io.mem_to_ooo.lsTopdownInfo := loadUnits.map(_.io.lsTopdownInfo) ++ hybridUnits.map(_.io.ldu_io.lsTopdownInfo) 764*c590fb32Scz4e 765*c590fb32Scz4e // trigger 766*c590fb32Scz4e val tdata = RegInit(VecInit(Seq.fill(TriggerNum)(0.U.asTypeOf(new MatchTriggerIO)))) 767*c590fb32Scz4e val tEnable = RegInit(VecInit(Seq.fill(TriggerNum)(false.B))) 768*c590fb32Scz4e tEnable := csrCtrl.mem_trigger.tEnableVec 769*c590fb32Scz4e when(csrCtrl.mem_trigger.tUpdate.valid) { 770*c590fb32Scz4e tdata(csrCtrl.mem_trigger.tUpdate.bits.addr) := csrCtrl.mem_trigger.tUpdate.bits.tdata 771*c590fb32Scz4e } 772*c590fb32Scz4e val triggerCanRaiseBpExp = csrCtrl.mem_trigger.triggerCanRaiseBpExp 773*c590fb32Scz4e val debugMode = csrCtrl.mem_trigger.debugMode 774*c590fb32Scz4e 775*c590fb32Scz4e val backendTriggerTimingVec = VecInit(tdata.map(_.timing)) 776*c590fb32Scz4e val backendTriggerChainVec = VecInit(tdata.map(_.chain)) 777*c590fb32Scz4e 778*c590fb32Scz4e XSDebug(tEnable.asUInt.orR, "Debug Mode: At least one store trigger is enabled\n") 779*c590fb32Scz4e for (j <- 0 until TriggerNum) 780*c590fb32Scz4e PrintTriggerInfo(tEnable(j), tdata(j)) 781*c590fb32Scz4e 782*c590fb32Scz4e // The segment instruction is executed atomically. 783*c590fb32Scz4e // After the segment instruction directive starts executing, no other instructions should be executed. 784*c590fb32Scz4e val vSegmentFlag = RegInit(false.B) 785*c590fb32Scz4e 786*c590fb32Scz4e when(GatedValidRegNext(vSegmentUnit.io.in.fire)) { 787*c590fb32Scz4e vSegmentFlag := true.B 788*c590fb32Scz4e }.elsewhen(GatedValidRegNext(vSegmentUnit.io.uopwriteback.valid)) { 789*c590fb32Scz4e vSegmentFlag := false.B 790*c590fb32Scz4e } 791*c590fb32Scz4e 792*c590fb32Scz4e // LoadUnit 793*c590fb32Scz4e val correctMissTrain = Constantin.createRecord(s"CorrectMissTrain$hartId", initValue = false) 794*c590fb32Scz4e 795*c590fb32Scz4e for (i <- 0 until LduCnt) { 796*c590fb32Scz4e loadUnits(i).io.redirect <> redirect 797*c590fb32Scz4e 798*c590fb32Scz4e // get input form dispatch 799*c590fb32Scz4e loadUnits(i).io.ldin <> io.ooo_to_mem.issueLda(i) 800*c590fb32Scz4e loadUnits(i).io.feedback_slow <> io.mem_to_ooo.ldaIqFeedback(i).feedbackSlow 801*c590fb32Scz4e io.mem_to_ooo.ldaIqFeedback(i).feedbackFast := DontCare 802*c590fb32Scz4e loadUnits(i).io.correctMissTrain := correctMissTrain 803*c590fb32Scz4e io.mem_to_ooo.ldCancel.drop(HyuCnt)(i) := loadUnits(i).io.ldCancel 804*c590fb32Scz4e io.mem_to_ooo.wakeup.drop(HyuCnt)(i) := loadUnits(i).io.wakeup 805*c590fb32Scz4e 806*c590fb32Scz4e // vector 807*c590fb32Scz4e if (i < VlduCnt) { 808*c590fb32Scz4e loadUnits(i).io.vecldout.ready := false.B 809*c590fb32Scz4e } else { 810*c590fb32Scz4e loadUnits(i).io.vecldin.valid := false.B 811*c590fb32Scz4e loadUnits(i).io.vecldin.bits := DontCare 812*c590fb32Scz4e loadUnits(i).io.vecldout.ready := false.B 813*c590fb32Scz4e } 814*c590fb32Scz4e 815*c590fb32Scz4e // fast replay 816*c590fb32Scz4e loadUnits(i).io.fast_rep_in <> loadUnits(i).io.fast_rep_out 817*c590fb32Scz4e 818*c590fb32Scz4e // SoftPrefetch to frontend (prefetch.i) 819*c590fb32Scz4e loadUnits(i).io.ifetchPrefetch <> io.ifetchPrefetch(i) 820*c590fb32Scz4e 821*c590fb32Scz4e // dcache access 822*c590fb32Scz4e loadUnits(i).io.dcache <> dcache.io.lsu.load(i) 823*c590fb32Scz4e if(i == 0){ 824*c590fb32Scz4e vSegmentUnit.io.rdcache := DontCare 825*c590fb32Scz4e dcache.io.lsu.load(i).req.valid := loadUnits(i).io.dcache.req.valid || vSegmentUnit.io.rdcache.req.valid 826*c590fb32Scz4e dcache.io.lsu.load(i).req.bits := Mux1H(Seq( 827*c590fb32Scz4e vSegmentUnit.io.rdcache.req.valid -> vSegmentUnit.io.rdcache.req.bits, 828*c590fb32Scz4e loadUnits(i).io.dcache.req.valid -> loadUnits(i).io.dcache.req.bits 829*c590fb32Scz4e )) 830*c590fb32Scz4e vSegmentUnit.io.rdcache.req.ready := dcache.io.lsu.load(i).req.ready 831*c590fb32Scz4e } 832*c590fb32Scz4e 833*c590fb32Scz4e // Dcache requests must also be preempted by the segment. 834*c590fb32Scz4e when(vSegmentFlag){ 835*c590fb32Scz4e loadUnits(i).io.dcache.req.ready := false.B // Dcache is preempted. 836*c590fb32Scz4e 837*c590fb32Scz4e dcache.io.lsu.load(0).pf_source := vSegmentUnit.io.rdcache.pf_source 838*c590fb32Scz4e dcache.io.lsu.load(0).s1_paddr_dup_lsu := vSegmentUnit.io.rdcache.s1_paddr_dup_lsu 839*c590fb32Scz4e dcache.io.lsu.load(0).s1_paddr_dup_dcache := vSegmentUnit.io.rdcache.s1_paddr_dup_dcache 840*c590fb32Scz4e dcache.io.lsu.load(0).s1_kill := vSegmentUnit.io.rdcache.s1_kill 841*c590fb32Scz4e dcache.io.lsu.load(0).s2_kill := vSegmentUnit.io.rdcache.s2_kill 842*c590fb32Scz4e dcache.io.lsu.load(0).s0_pc := vSegmentUnit.io.rdcache.s0_pc 843*c590fb32Scz4e dcache.io.lsu.load(0).s1_pc := vSegmentUnit.io.rdcache.s1_pc 844*c590fb32Scz4e dcache.io.lsu.load(0).s2_pc := vSegmentUnit.io.rdcache.s2_pc 845*c590fb32Scz4e dcache.io.lsu.load(0).is128Req := vSegmentUnit.io.rdcache.is128Req 846*c590fb32Scz4e }.otherwise { 847*c590fb32Scz4e loadUnits(i).io.dcache.req.ready := dcache.io.lsu.load(i).req.ready 848*c590fb32Scz4e 849*c590fb32Scz4e dcache.io.lsu.load(0).pf_source := loadUnits(0).io.dcache.pf_source 850*c590fb32Scz4e dcache.io.lsu.load(0).s1_paddr_dup_lsu := loadUnits(0).io.dcache.s1_paddr_dup_lsu 851*c590fb32Scz4e dcache.io.lsu.load(0).s1_paddr_dup_dcache := loadUnits(0).io.dcache.s1_paddr_dup_dcache 852*c590fb32Scz4e dcache.io.lsu.load(0).s1_kill := loadUnits(0).io.dcache.s1_kill 853*c590fb32Scz4e dcache.io.lsu.load(0).s2_kill := loadUnits(0).io.dcache.s2_kill 854*c590fb32Scz4e dcache.io.lsu.load(0).s0_pc := loadUnits(0).io.dcache.s0_pc 855*c590fb32Scz4e dcache.io.lsu.load(0).s1_pc := loadUnits(0).io.dcache.s1_pc 856*c590fb32Scz4e dcache.io.lsu.load(0).s2_pc := loadUnits(0).io.dcache.s2_pc 857*c590fb32Scz4e dcache.io.lsu.load(0).is128Req := loadUnits(0).io.dcache.is128Req 858*c590fb32Scz4e } 859*c590fb32Scz4e 860*c590fb32Scz4e // forward 861*c590fb32Scz4e loadUnits(i).io.lsq.forward <> lsq.io.forward(i) 862*c590fb32Scz4e loadUnits(i).io.sbuffer <> sbuffer.io.forward(i) 863*c590fb32Scz4e loadUnits(i).io.ubuffer <> uncache.io.forward(i) 864*c590fb32Scz4e loadUnits(i).io.tl_d_channel := dcache.io.lsu.forward_D(i) 865*c590fb32Scz4e loadUnits(i).io.forward_mshr <> dcache.io.lsu.forward_mshr(i) 866*c590fb32Scz4e // ld-ld violation check 867*c590fb32Scz4e loadUnits(i).io.lsq.ldld_nuke_query <> lsq.io.ldu.ldld_nuke_query(i) 868*c590fb32Scz4e loadUnits(i).io.lsq.stld_nuke_query <> lsq.io.ldu.stld_nuke_query(i) 869*c590fb32Scz4e loadUnits(i).io.csrCtrl <> csrCtrl 870*c590fb32Scz4e // dcache refill req 871*c590fb32Scz4e // loadUnits(i).io.refill <> delayedDcacheRefill 872*c590fb32Scz4e // dtlb 873*c590fb32Scz4e loadUnits(i).io.tlb <> dtlb_reqs.take(LduCnt)(i) 874*c590fb32Scz4e if(i == 0 ){ // port 0 assign to vsegmentUnit 875*c590fb32Scz4e val vsegmentDtlbReqValid = vSegmentUnit.io.dtlb.req.valid // segment tlb resquest need to delay 1 cycle 876*c590fb32Scz4e dtlb_reqs.take(LduCnt)(i).req.valid := loadUnits(i).io.tlb.req.valid || RegNext(vsegmentDtlbReqValid) 877*c590fb32Scz4e vSegmentUnit.io.dtlb.req.ready := dtlb_reqs.take(LduCnt)(i).req.ready 878*c590fb32Scz4e dtlb_reqs.take(LduCnt)(i).req.bits := ParallelPriorityMux(Seq( 879*c590fb32Scz4e RegNext(vsegmentDtlbReqValid) -> RegEnable(vSegmentUnit.io.dtlb.req.bits, vsegmentDtlbReqValid), 880*c590fb32Scz4e loadUnits(i).io.tlb.req.valid -> loadUnits(i).io.tlb.req.bits 881*c590fb32Scz4e )) 882*c590fb32Scz4e } 883*c590fb32Scz4e // pmp 884*c590fb32Scz4e loadUnits(i).io.pmp <> pmp_check(i).resp 885*c590fb32Scz4e // st-ld violation query 886*c590fb32Scz4e val stld_nuke_query = storeUnits.map(_.io.stld_nuke_query) ++ hybridUnits.map(_.io.stu_io.stld_nuke_query) 887*c590fb32Scz4e for (s <- 0 until StorePipelineWidth) { 888*c590fb32Scz4e loadUnits(i).io.stld_nuke_query(s) := stld_nuke_query(s) 889*c590fb32Scz4e } 890*c590fb32Scz4e loadUnits(i).io.lq_rep_full <> lsq.io.lq_rep_full 891*c590fb32Scz4e // load prefetch train 892*c590fb32Scz4e prefetcherOpt.foreach(pf => { 893*c590fb32Scz4e // sms will train on all miss load sources 894*c590fb32Scz4e val source = loadUnits(i).io.prefetch_train 895*c590fb32Scz4e pf.io.ld_in(i).valid := Mux(pf_train_on_hit, 896*c590fb32Scz4e source.valid, 897*c590fb32Scz4e source.valid && source.bits.isFirstIssue && source.bits.miss 898*c590fb32Scz4e ) 899*c590fb32Scz4e pf.io.ld_in(i).bits := source.bits 900*c590fb32Scz4e val loadPc = RegNext(io.ooo_to_mem.issueLda(i).bits.uop.pc) // for s1 901*c590fb32Scz4e pf.io.ld_in(i).bits.uop.pc := Mux( 902*c590fb32Scz4e loadUnits(i).io.s2_ptr_chasing, 903*c590fb32Scz4e RegEnable(loadPc, loadUnits(i).io.s2_prefetch_spec), 904*c590fb32Scz4e RegEnable(RegEnable(loadPc, loadUnits(i).io.s1_prefetch_spec), loadUnits(i).io.s2_prefetch_spec) 905*c590fb32Scz4e ) 906*c590fb32Scz4e }) 907*c590fb32Scz4e l1PrefetcherOpt.foreach(pf => { 908*c590fb32Scz4e // stream will train on all load sources 909*c590fb32Scz4e val source = loadUnits(i).io.prefetch_train_l1 910*c590fb32Scz4e pf.io.ld_in(i).valid := source.valid && source.bits.isFirstIssue 911*c590fb32Scz4e pf.io.ld_in(i).bits := source.bits 912*c590fb32Scz4e }) 913*c590fb32Scz4e 914*c590fb32Scz4e // load to load fast forward: load(i) prefers data(i) 915*c590fb32Scz4e val l2l_fwd_out = loadUnits.map(_.io.l2l_fwd_out) ++ hybridUnits.map(_.io.ldu_io.l2l_fwd_out) 916*c590fb32Scz4e val fastPriority = (i until LduCnt + HyuCnt) ++ (0 until i) 917*c590fb32Scz4e val fastValidVec = fastPriority.map(j => l2l_fwd_out(j).valid) 918*c590fb32Scz4e val fastDataVec = fastPriority.map(j => l2l_fwd_out(j).data) 919*c590fb32Scz4e val fastErrorVec = fastPriority.map(j => l2l_fwd_out(j).dly_ld_err) 920*c590fb32Scz4e val fastMatchVec = fastPriority.map(j => io.ooo_to_mem.loadFastMatch(i)(j)) 921*c590fb32Scz4e loadUnits(i).io.l2l_fwd_in.valid := VecInit(fastValidVec).asUInt.orR 922*c590fb32Scz4e loadUnits(i).io.l2l_fwd_in.data := ParallelPriorityMux(fastValidVec, fastDataVec) 923*c590fb32Scz4e loadUnits(i).io.l2l_fwd_in.dly_ld_err := ParallelPriorityMux(fastValidVec, fastErrorVec) 924*c590fb32Scz4e val fastMatch = ParallelPriorityMux(fastValidVec, fastMatchVec) 925*c590fb32Scz4e loadUnits(i).io.ld_fast_match := fastMatch 926*c590fb32Scz4e loadUnits(i).io.ld_fast_imm := io.ooo_to_mem.loadFastImm(i) 927*c590fb32Scz4e loadUnits(i).io.ld_fast_fuOpType := io.ooo_to_mem.loadFastFuOpType(i) 928*c590fb32Scz4e loadUnits(i).io.replay <> lsq.io.replay(i) 929*c590fb32Scz4e 930*c590fb32Scz4e val l2_hint = RegNext(io.l2_hint) 931*c590fb32Scz4e 932*c590fb32Scz4e // L2 Hint for DCache 933*c590fb32Scz4e dcache.io.l2_hint <> l2_hint 934*c590fb32Scz4e 935*c590fb32Scz4e loadUnits(i).io.l2_hint <> l2_hint 936*c590fb32Scz4e loadUnits(i).io.tlb_hint.id := dtlbRepeater.io.hint.get.req(i).id 937*c590fb32Scz4e loadUnits(i).io.tlb_hint.full := dtlbRepeater.io.hint.get.req(i).full || 938*c590fb32Scz4e tlbreplay_reg(i) || dtlb_ld0_tlbreplay_reg(i) 939*c590fb32Scz4e 940*c590fb32Scz4e // passdown to lsq (load s2) 941*c590fb32Scz4e lsq.io.ldu.ldin(i) <> loadUnits(i).io.lsq.ldin 942*c590fb32Scz4e if (i == UncacheWBPort) { 943*c590fb32Scz4e lsq.io.ldout(i) <> loadUnits(i).io.lsq.uncache 944*c590fb32Scz4e } else { 945*c590fb32Scz4e lsq.io.ldout(i).ready := true.B 946*c590fb32Scz4e loadUnits(i).io.lsq.uncache.valid := false.B 947*c590fb32Scz4e loadUnits(i).io.lsq.uncache.bits := DontCare 948*c590fb32Scz4e } 949*c590fb32Scz4e lsq.io.ld_raw_data(i) <> loadUnits(i).io.lsq.ld_raw_data 950*c590fb32Scz4e lsq.io.ncOut(i) <> loadUnits(i).io.lsq.nc_ldin 951*c590fb32Scz4e lsq.io.l2_hint.valid := l2_hint.valid 952*c590fb32Scz4e lsq.io.l2_hint.bits.sourceId := l2_hint.bits.sourceId 953*c590fb32Scz4e lsq.io.l2_hint.bits.isKeyword := l2_hint.bits.isKeyword 954*c590fb32Scz4e 955*c590fb32Scz4e lsq.io.tlb_hint <> dtlbRepeater.io.hint.get 956*c590fb32Scz4e 957*c590fb32Scz4e // connect misalignBuffer 958*c590fb32Scz4e loadMisalignBuffer.io.req(i) <> loadUnits(i).io.misalign_buf 959*c590fb32Scz4e 960*c590fb32Scz4e if (i == MisalignWBPort) { 961*c590fb32Scz4e loadUnits(i).io.misalign_ldin <> loadMisalignBuffer.io.splitLoadReq 962*c590fb32Scz4e loadUnits(i).io.misalign_ldout <> loadMisalignBuffer.io.splitLoadResp 963*c590fb32Scz4e } else { 964*c590fb32Scz4e loadUnits(i).io.misalign_ldin.valid := false.B 965*c590fb32Scz4e loadUnits(i).io.misalign_ldin.bits := DontCare 966*c590fb32Scz4e } 967*c590fb32Scz4e 968*c590fb32Scz4e // alter writeback exception info 969*c590fb32Scz4e io.mem_to_ooo.s3_delayed_load_error(i) := loadUnits(i).io.s3_dly_ld_err 970*c590fb32Scz4e 971*c590fb32Scz4e // update mem dependency predictor 972*c590fb32Scz4e // io.memPredUpdate(i) := DontCare 973*c590fb32Scz4e 974*c590fb32Scz4e // -------------------------------- 975*c590fb32Scz4e // Load Triggers 976*c590fb32Scz4e // -------------------------------- 977*c590fb32Scz4e loadUnits(i).io.fromCsrTrigger.tdataVec := tdata 978*c590fb32Scz4e loadUnits(i).io.fromCsrTrigger.tEnableVec := tEnable 979*c590fb32Scz4e loadUnits(i).io.fromCsrTrigger.triggerCanRaiseBpExp := triggerCanRaiseBpExp 980*c590fb32Scz4e loadUnits(i).io.fromCsrTrigger.debugMode := debugMode 981*c590fb32Scz4e } 982*c590fb32Scz4e 983*c590fb32Scz4e for (i <- 0 until HyuCnt) { 984*c590fb32Scz4e hybridUnits(i).io.redirect <> redirect 985*c590fb32Scz4e 986*c590fb32Scz4e // get input from dispatch 987*c590fb32Scz4e hybridUnits(i).io.lsin <> io.ooo_to_mem.issueHya(i) 988*c590fb32Scz4e hybridUnits(i).io.feedback_slow <> io.mem_to_ooo.hyuIqFeedback(i).feedbackSlow 989*c590fb32Scz4e hybridUnits(i).io.feedback_fast <> io.mem_to_ooo.hyuIqFeedback(i).feedbackFast 990*c590fb32Scz4e hybridUnits(i).io.correctMissTrain := correctMissTrain 991*c590fb32Scz4e io.mem_to_ooo.ldCancel.take(HyuCnt)(i) := hybridUnits(i).io.ldu_io.ldCancel 992*c590fb32Scz4e io.mem_to_ooo.wakeup.take(HyuCnt)(i) := hybridUnits(i).io.ldu_io.wakeup 993*c590fb32Scz4e 994*c590fb32Scz4e // ------------------------------------ 995*c590fb32Scz4e // Load Port 996*c590fb32Scz4e // ------------------------------------ 997*c590fb32Scz4e // fast replay 998*c590fb32Scz4e hybridUnits(i).io.ldu_io.fast_rep_in <> hybridUnits(i).io.ldu_io.fast_rep_out 999*c590fb32Scz4e 1000*c590fb32Scz4e // get input from dispatch 1001*c590fb32Scz4e hybridUnits(i).io.ldu_io.dcache <> dcache.io.lsu.load(LduCnt + i) 1002*c590fb32Scz4e hybridUnits(i).io.stu_io.dcache <> dcache.io.lsu.sta(StaCnt + i) 1003*c590fb32Scz4e 1004*c590fb32Scz4e // dcache access 1005*c590fb32Scz4e hybridUnits(i).io.ldu_io.lsq.forward <> lsq.io.forward(LduCnt + i) 1006*c590fb32Scz4e // forward 1007*c590fb32Scz4e hybridUnits(i).io.ldu_io.sbuffer <> sbuffer.io.forward(LduCnt + i) 1008*c590fb32Scz4e hybridUnits(i).io.ldu_io.ubuffer <> uncache.io.forward(LduCnt + i) 1009*c590fb32Scz4e // hybridUnits(i).io.ldu_io.vec_forward <> vsFlowQueue.io.forward(LduCnt + i) 1010*c590fb32Scz4e hybridUnits(i).io.ldu_io.vec_forward := DontCare 1011*c590fb32Scz4e hybridUnits(i).io.ldu_io.tl_d_channel := dcache.io.lsu.forward_D(LduCnt + i) 1012*c590fb32Scz4e hybridUnits(i).io.ldu_io.forward_mshr <> dcache.io.lsu.forward_mshr(LduCnt + i) 1013*c590fb32Scz4e // ld-ld violation check 1014*c590fb32Scz4e hybridUnits(i).io.ldu_io.lsq.ldld_nuke_query <> lsq.io.ldu.ldld_nuke_query(LduCnt + i) 1015*c590fb32Scz4e hybridUnits(i).io.ldu_io.lsq.stld_nuke_query <> lsq.io.ldu.stld_nuke_query(LduCnt + i) 1016*c590fb32Scz4e hybridUnits(i).io.csrCtrl <> csrCtrl 1017*c590fb32Scz4e // dcache refill req 1018*c590fb32Scz4e hybridUnits(i).io.ldu_io.tlb_hint.id := dtlbRepeater.io.hint.get.req(LduCnt + i).id 1019*c590fb32Scz4e hybridUnits(i).io.ldu_io.tlb_hint.full := dtlbRepeater.io.hint.get.req(LduCnt + i).full || 1020*c590fb32Scz4e tlbreplay_reg(LduCnt + i) || dtlb_ld0_tlbreplay_reg(LduCnt + i) 1021*c590fb32Scz4e 1022*c590fb32Scz4e // dtlb 1023*c590fb32Scz4e hybridUnits(i).io.tlb <> dtlb_ld.head.requestor(LduCnt + i) 1024*c590fb32Scz4e // pmp 1025*c590fb32Scz4e hybridUnits(i).io.pmp <> pmp_check.drop(LduCnt)(i).resp 1026*c590fb32Scz4e // st-ld violation query 1027*c590fb32Scz4e val stld_nuke_query = VecInit(storeUnits.map(_.io.stld_nuke_query) ++ hybridUnits.map(_.io.stu_io.stld_nuke_query)) 1028*c590fb32Scz4e hybridUnits(i).io.ldu_io.stld_nuke_query := stld_nuke_query 1029*c590fb32Scz4e hybridUnits(i).io.ldu_io.lq_rep_full <> lsq.io.lq_rep_full 1030*c590fb32Scz4e // load prefetch train 1031*c590fb32Scz4e prefetcherOpt.foreach(pf => { 1032*c590fb32Scz4e val source = hybridUnits(i).io.prefetch_train 1033*c590fb32Scz4e pf.io.ld_in(LduCnt + i).valid := Mux(pf_train_on_hit, 1034*c590fb32Scz4e source.valid, 1035*c590fb32Scz4e source.valid && source.bits.isFirstIssue && source.bits.miss 1036*c590fb32Scz4e ) 1037*c590fb32Scz4e pf.io.ld_in(LduCnt + i).bits := source.bits 1038*c590fb32Scz4e pf.io.ld_in(LduCnt + i).bits.uop.pc := Mux(hybridUnits(i).io.ldu_io.s2_ptr_chasing, io.ooo_to_mem.hybridPc(i), RegNext(io.ooo_to_mem.hybridPc(i))) 1039*c590fb32Scz4e }) 1040*c590fb32Scz4e l1PrefetcherOpt.foreach(pf => { 1041*c590fb32Scz4e // stream will train on all load sources 1042*c590fb32Scz4e val source = hybridUnits(i).io.prefetch_train_l1 1043*c590fb32Scz4e pf.io.ld_in(LduCnt + i).valid := source.valid && source.bits.isFirstIssue && 1044*c590fb32Scz4e FuType.isLoad(source.bits.uop.fuType) 1045*c590fb32Scz4e pf.io.ld_in(LduCnt + i).bits := source.bits 1046*c590fb32Scz4e pf.io.st_in(StaCnt + i).valid := false.B 1047*c590fb32Scz4e pf.io.st_in(StaCnt + i).bits := DontCare 1048*c590fb32Scz4e }) 1049*c590fb32Scz4e prefetcherOpt.foreach(pf => { 1050*c590fb32Scz4e val source = hybridUnits(i).io.prefetch_train 1051*c590fb32Scz4e pf.io.st_in(StaCnt + i).valid := Mux(pf_train_on_hit, 1052*c590fb32Scz4e source.valid, 1053*c590fb32Scz4e source.valid && source.bits.isFirstIssue && source.bits.miss 1054*c590fb32Scz4e ) && FuType.isStore(source.bits.uop.fuType) 1055*c590fb32Scz4e pf.io.st_in(StaCnt + i).bits := source.bits 1056*c590fb32Scz4e pf.io.st_in(StaCnt + i).bits.uop.pc := RegNext(io.ooo_to_mem.hybridPc(i)) 1057*c590fb32Scz4e }) 1058*c590fb32Scz4e 1059*c590fb32Scz4e // load to load fast forward: load(i) prefers data(i) 1060*c590fb32Scz4e val l2l_fwd_out = loadUnits.map(_.io.l2l_fwd_out) ++ hybridUnits.map(_.io.ldu_io.l2l_fwd_out) 1061*c590fb32Scz4e val fastPriority = (LduCnt + i until LduCnt + HyuCnt) ++ (0 until LduCnt + i) 1062*c590fb32Scz4e val fastValidVec = fastPriority.map(j => l2l_fwd_out(j).valid) 1063*c590fb32Scz4e val fastDataVec = fastPriority.map(j => l2l_fwd_out(j).data) 1064*c590fb32Scz4e val fastErrorVec = fastPriority.map(j => l2l_fwd_out(j).dly_ld_err) 1065*c590fb32Scz4e val fastMatchVec = fastPriority.map(j => io.ooo_to_mem.loadFastMatch(LduCnt + i)(j)) 1066*c590fb32Scz4e hybridUnits(i).io.ldu_io.l2l_fwd_in.valid := VecInit(fastValidVec).asUInt.orR 1067*c590fb32Scz4e hybridUnits(i).io.ldu_io.l2l_fwd_in.data := ParallelPriorityMux(fastValidVec, fastDataVec) 1068*c590fb32Scz4e hybridUnits(i).io.ldu_io.l2l_fwd_in.dly_ld_err := ParallelPriorityMux(fastValidVec, fastErrorVec) 1069*c590fb32Scz4e val fastMatch = ParallelPriorityMux(fastValidVec, fastMatchVec) 1070*c590fb32Scz4e hybridUnits(i).io.ldu_io.ld_fast_match := fastMatch 1071*c590fb32Scz4e hybridUnits(i).io.ldu_io.ld_fast_imm := io.ooo_to_mem.loadFastImm(LduCnt + i) 1072*c590fb32Scz4e hybridUnits(i).io.ldu_io.ld_fast_fuOpType := io.ooo_to_mem.loadFastFuOpType(LduCnt + i) 1073*c590fb32Scz4e hybridUnits(i).io.ldu_io.replay <> lsq.io.replay(LduCnt + i) 1074*c590fb32Scz4e hybridUnits(i).io.ldu_io.l2_hint <> io.l2_hint 1075*c590fb32Scz4e 1076*c590fb32Scz4e // uncache 1077*c590fb32Scz4e lsq.io.ldout.drop(LduCnt)(i) <> hybridUnits(i).io.ldu_io.lsq.uncache 1078*c590fb32Scz4e lsq.io.ld_raw_data.drop(LduCnt)(i) <> hybridUnits(i).io.ldu_io.lsq.ld_raw_data 1079*c590fb32Scz4e 1080*c590fb32Scz4e 1081*c590fb32Scz4e // passdown to lsq (load s2) 1082*c590fb32Scz4e hybridUnits(i).io.ldu_io.lsq.nc_ldin.valid := false.B 1083*c590fb32Scz4e hybridUnits(i).io.ldu_io.lsq.nc_ldin.bits := DontCare 1084*c590fb32Scz4e lsq.io.ldu.ldin(LduCnt + i) <> hybridUnits(i).io.ldu_io.lsq.ldin 1085*c590fb32Scz4e // Lsq to sta unit 1086*c590fb32Scz4e lsq.io.sta.storeMaskIn(StaCnt + i) <> hybridUnits(i).io.stu_io.st_mask_out 1087*c590fb32Scz4e 1088*c590fb32Scz4e // Lsq to std unit's rs 1089*c590fb32Scz4e lsq.io.std.storeDataIn(StaCnt + i) := stData(StaCnt + i) 1090*c590fb32Scz4e lsq.io.std.storeDataIn(StaCnt + i).valid := stData(StaCnt + i).valid && !st_data_atomics(StaCnt + i) 1091*c590fb32Scz4e // prefetch 1092*c590fb32Scz4e hybridUnits(i).io.stu_io.prefetch_req <> sbuffer.io.store_prefetch(StaCnt + i) 1093*c590fb32Scz4e 1094*c590fb32Scz4e io.mem_to_ooo.s3_delayed_load_error(LduCnt + i) := hybridUnits(i).io.ldu_io.s3_dly_ld_err 1095*c590fb32Scz4e 1096*c590fb32Scz4e // ------------------------------------ 1097*c590fb32Scz4e // Store Port 1098*c590fb32Scz4e // ------------------------------------ 1099*c590fb32Scz4e hybridUnits(i).io.stu_io.lsq <> lsq.io.sta.storeAddrIn.takeRight(HyuCnt)(i) 1100*c590fb32Scz4e hybridUnits(i).io.stu_io.lsq_replenish <> lsq.io.sta.storeAddrInRe.takeRight(HyuCnt)(i) 1101*c590fb32Scz4e 1102*c590fb32Scz4e lsq.io.sta.storeMaskIn.takeRight(HyuCnt)(i) <> hybridUnits(i).io.stu_io.st_mask_out 1103*c590fb32Scz4e io.mem_to_ooo.stIn.takeRight(HyuCnt)(i).valid := hybridUnits(i).io.stu_io.issue.valid 1104*c590fb32Scz4e io.mem_to_ooo.stIn.takeRight(HyuCnt)(i).bits := hybridUnits(i).io.stu_io.issue.bits 1105*c590fb32Scz4e 1106*c590fb32Scz4e // ------------------------------------ 1107*c590fb32Scz4e // Vector Store Port 1108*c590fb32Scz4e // ------------------------------------ 1109*c590fb32Scz4e hybridUnits(i).io.vec_stu_io.isFirstIssue := true.B 1110*c590fb32Scz4e 1111*c590fb32Scz4e // ------------------------- 1112*c590fb32Scz4e // Store Triggers 1113*c590fb32Scz4e // ------------------------- 1114*c590fb32Scz4e hybridUnits(i).io.fromCsrTrigger.tdataVec := tdata 1115*c590fb32Scz4e hybridUnits(i).io.fromCsrTrigger.tEnableVec := tEnable 1116*c590fb32Scz4e hybridUnits(i).io.fromCsrTrigger.triggerCanRaiseBpExp := triggerCanRaiseBpExp 1117*c590fb32Scz4e hybridUnits(i).io.fromCsrTrigger.debugMode := debugMode 1118*c590fb32Scz4e } 1119*c590fb32Scz4e 1120*c590fb32Scz4e // misalignBuffer 1121*c590fb32Scz4e loadMisalignBuffer.io.redirect <> redirect 1122*c590fb32Scz4e loadMisalignBuffer.io.rob.lcommit := io.ooo_to_mem.lsqio.lcommit 1123*c590fb32Scz4e loadMisalignBuffer.io.rob.scommit := io.ooo_to_mem.lsqio.scommit 1124*c590fb32Scz4e loadMisalignBuffer.io.rob.pendingMMIOld := io.ooo_to_mem.lsqio.pendingMMIOld 1125*c590fb32Scz4e loadMisalignBuffer.io.rob.pendingld := io.ooo_to_mem.lsqio.pendingld 1126*c590fb32Scz4e loadMisalignBuffer.io.rob.pendingst := io.ooo_to_mem.lsqio.pendingst 1127*c590fb32Scz4e loadMisalignBuffer.io.rob.pendingVst := io.ooo_to_mem.lsqio.pendingVst 1128*c590fb32Scz4e loadMisalignBuffer.io.rob.commit := io.ooo_to_mem.lsqio.commit 1129*c590fb32Scz4e loadMisalignBuffer.io.rob.pendingPtr := io.ooo_to_mem.lsqio.pendingPtr 1130*c590fb32Scz4e loadMisalignBuffer.io.rob.pendingPtrNext := io.ooo_to_mem.lsqio.pendingPtrNext 1131*c590fb32Scz4e 1132*c590fb32Scz4e lsq.io.loadMisalignFull := loadMisalignBuffer.io.loadMisalignFull 1133*c590fb32Scz4e 1134*c590fb32Scz4e storeMisalignBuffer.io.redirect <> redirect 1135*c590fb32Scz4e storeMisalignBuffer.io.rob.lcommit := io.ooo_to_mem.lsqio.lcommit 1136*c590fb32Scz4e storeMisalignBuffer.io.rob.scommit := io.ooo_to_mem.lsqio.scommit 1137*c590fb32Scz4e storeMisalignBuffer.io.rob.pendingMMIOld := io.ooo_to_mem.lsqio.pendingMMIOld 1138*c590fb32Scz4e storeMisalignBuffer.io.rob.pendingld := io.ooo_to_mem.lsqio.pendingld 1139*c590fb32Scz4e storeMisalignBuffer.io.rob.pendingst := io.ooo_to_mem.lsqio.pendingst 1140*c590fb32Scz4e storeMisalignBuffer.io.rob.pendingVst := io.ooo_to_mem.lsqio.pendingVst 1141*c590fb32Scz4e storeMisalignBuffer.io.rob.commit := io.ooo_to_mem.lsqio.commit 1142*c590fb32Scz4e storeMisalignBuffer.io.rob.pendingPtr := io.ooo_to_mem.lsqio.pendingPtr 1143*c590fb32Scz4e storeMisalignBuffer.io.rob.pendingPtrNext := io.ooo_to_mem.lsqio.pendingPtrNext 1144*c590fb32Scz4e 1145*c590fb32Scz4e lsq.io.maControl <> storeMisalignBuffer.io.sqControl 1146*c590fb32Scz4e 1147*c590fb32Scz4e lsq.io.cmoOpReq <> dcache.io.cmoOpReq 1148*c590fb32Scz4e lsq.io.cmoOpResp <> dcache.io.cmoOpResp 1149*c590fb32Scz4e 1150*c590fb32Scz4e // Prefetcher 1151*c590fb32Scz4e val StreamDTLBPortIndex = TlbStartVec(dtlb_ld_idx) + LduCnt + HyuCnt 1152*c590fb32Scz4e val PrefetcherDTLBPortIndex = TlbStartVec(dtlb_pf_idx) 1153*c590fb32Scz4e val L2toL1DLBPortIndex = TlbStartVec(dtlb_pf_idx) + 1 1154*c590fb32Scz4e prefetcherOpt match { 1155*c590fb32Scz4e case Some(pf) => 1156*c590fb32Scz4e dtlb_reqs(PrefetcherDTLBPortIndex) <> pf.io.tlb_req 1157*c590fb32Scz4e pf.io.pmp_resp := pmp_check(PrefetcherDTLBPortIndex).resp 1158*c590fb32Scz4e case None => 1159*c590fb32Scz4e dtlb_reqs(PrefetcherDTLBPortIndex) := DontCare 1160*c590fb32Scz4e dtlb_reqs(PrefetcherDTLBPortIndex).req.valid := false.B 1161*c590fb32Scz4e dtlb_reqs(PrefetcherDTLBPortIndex).resp.ready := true.B 1162*c590fb32Scz4e } 1163*c590fb32Scz4e l1PrefetcherOpt match { 1164*c590fb32Scz4e case Some(pf) => 1165*c590fb32Scz4e dtlb_reqs(StreamDTLBPortIndex) <> pf.io.tlb_req 1166*c590fb32Scz4e pf.io.pmp_resp := pmp_check(StreamDTLBPortIndex).resp 1167*c590fb32Scz4e case None => 1168*c590fb32Scz4e dtlb_reqs(StreamDTLBPortIndex) := DontCare 1169*c590fb32Scz4e dtlb_reqs(StreamDTLBPortIndex).req.valid := false.B 1170*c590fb32Scz4e dtlb_reqs(StreamDTLBPortIndex).resp.ready := true.B 1171*c590fb32Scz4e } 1172*c590fb32Scz4e dtlb_reqs(L2toL1DLBPortIndex) <> io.l2_tlb_req 1173*c590fb32Scz4e dtlb_reqs(L2toL1DLBPortIndex).resp.ready := true.B 1174*c590fb32Scz4e io.l2_pmp_resp := pmp_check(L2toL1DLBPortIndex).resp 1175*c590fb32Scz4e 1176*c590fb32Scz4e // StoreUnit 1177*c590fb32Scz4e for (i <- 0 until StdCnt) { 1178*c590fb32Scz4e stdExeUnits(i).io.flush <> redirect 1179*c590fb32Scz4e stdExeUnits(i).io.in.valid := io.ooo_to_mem.issueStd(i).valid 1180*c590fb32Scz4e io.ooo_to_mem.issueStd(i).ready := stdExeUnits(i).io.in.ready 1181*c590fb32Scz4e stdExeUnits(i).io.in.bits := io.ooo_to_mem.issueStd(i).bits 1182*c590fb32Scz4e } 1183*c590fb32Scz4e 1184*c590fb32Scz4e for (i <- 0 until StaCnt) { 1185*c590fb32Scz4e val stu = storeUnits(i) 1186*c590fb32Scz4e 1187*c590fb32Scz4e stu.io.redirect <> redirect 1188*c590fb32Scz4e stu.io.csrCtrl <> csrCtrl 1189*c590fb32Scz4e stu.io.dcache <> dcache.io.lsu.sta(i) 1190*c590fb32Scz4e stu.io.feedback_slow <> io.mem_to_ooo.staIqFeedback(i).feedbackSlow 1191*c590fb32Scz4e stu.io.stin <> io.ooo_to_mem.issueSta(i) 1192*c590fb32Scz4e stu.io.lsq <> lsq.io.sta.storeAddrIn(i) 1193*c590fb32Scz4e stu.io.lsq_replenish <> lsq.io.sta.storeAddrInRe(i) 1194*c590fb32Scz4e // dtlb 1195*c590fb32Scz4e stu.io.tlb <> dtlb_st.head.requestor(i) 1196*c590fb32Scz4e stu.io.pmp <> pmp_check(LduCnt + HyuCnt + 1 + i).resp 1197*c590fb32Scz4e 1198*c590fb32Scz4e // ------------------------- 1199*c590fb32Scz4e // Store Triggers 1200*c590fb32Scz4e // ------------------------- 1201*c590fb32Scz4e stu.io.fromCsrTrigger.tdataVec := tdata 1202*c590fb32Scz4e stu.io.fromCsrTrigger.tEnableVec := tEnable 1203*c590fb32Scz4e stu.io.fromCsrTrigger.triggerCanRaiseBpExp := triggerCanRaiseBpExp 1204*c590fb32Scz4e stu.io.fromCsrTrigger.debugMode := debugMode 1205*c590fb32Scz4e 1206*c590fb32Scz4e // prefetch 1207*c590fb32Scz4e stu.io.prefetch_req <> sbuffer.io.store_prefetch(i) 1208*c590fb32Scz4e 1209*c590fb32Scz4e // store unit does not need fast feedback 1210*c590fb32Scz4e io.mem_to_ooo.staIqFeedback(i).feedbackFast := DontCare 1211*c590fb32Scz4e 1212*c590fb32Scz4e // Lsq to sta unit 1213*c590fb32Scz4e lsq.io.sta.storeMaskIn(i) <> stu.io.st_mask_out 1214*c590fb32Scz4e 1215*c590fb32Scz4e // connect misalignBuffer 1216*c590fb32Scz4e storeMisalignBuffer.io.req(i) <> stu.io.misalign_buf 1217*c590fb32Scz4e 1218*c590fb32Scz4e if (i == 0) { 1219*c590fb32Scz4e stu.io.misalign_stin <> storeMisalignBuffer.io.splitStoreReq 1220*c590fb32Scz4e stu.io.misalign_stout <> storeMisalignBuffer.io.splitStoreResp 1221*c590fb32Scz4e } else { 1222*c590fb32Scz4e stu.io.misalign_stin.valid := false.B 1223*c590fb32Scz4e stu.io.misalign_stin.bits := DontCare 1224*c590fb32Scz4e } 1225*c590fb32Scz4e 1226*c590fb32Scz4e // Lsq to std unit's rs 1227*c590fb32Scz4e if (i < VstuCnt){ 1228*c590fb32Scz4e when (vsSplit(i).io.vstd.get.valid) { 1229*c590fb32Scz4e lsq.io.std.storeDataIn(i).valid := true.B 1230*c590fb32Scz4e lsq.io.std.storeDataIn(i).bits := vsSplit(i).io.vstd.get.bits 1231*c590fb32Scz4e stData(i).ready := false.B 1232*c590fb32Scz4e }.otherwise { 1233*c590fb32Scz4e lsq.io.std.storeDataIn(i).valid := stData(i).valid && !st_data_atomics(i) 1234*c590fb32Scz4e lsq.io.std.storeDataIn(i).bits.uop := stData(i).bits.uop 1235*c590fb32Scz4e lsq.io.std.storeDataIn(i).bits.data := stData(i).bits.data 1236*c590fb32Scz4e lsq.io.std.storeDataIn(i).bits.mask.map(_ := 0.U) 1237*c590fb32Scz4e lsq.io.std.storeDataIn(i).bits.vdIdx.map(_ := 0.U) 1238*c590fb32Scz4e lsq.io.std.storeDataIn(i).bits.vdIdxInField.map(_ := 0.U) 1239*c590fb32Scz4e stData(i).ready := true.B 1240*c590fb32Scz4e } 1241*c590fb32Scz4e } else { 1242*c590fb32Scz4e lsq.io.std.storeDataIn(i).valid := stData(i).valid && !st_data_atomics(i) 1243*c590fb32Scz4e lsq.io.std.storeDataIn(i).bits.uop := stData(i).bits.uop 1244*c590fb32Scz4e lsq.io.std.storeDataIn(i).bits.data := stData(i).bits.data 1245*c590fb32Scz4e lsq.io.std.storeDataIn(i).bits.mask.map(_ := 0.U) 1246*c590fb32Scz4e lsq.io.std.storeDataIn(i).bits.vdIdx.map(_ := 0.U) 1247*c590fb32Scz4e lsq.io.std.storeDataIn(i).bits.vdIdxInField.map(_ := 0.U) 1248*c590fb32Scz4e stData(i).ready := true.B 1249*c590fb32Scz4e } 1250*c590fb32Scz4e lsq.io.std.storeDataIn.map(_.bits.debug := 0.U.asTypeOf(new DebugBundle)) 1251*c590fb32Scz4e lsq.io.std.storeDataIn.foreach(_.bits.isFromLoadUnit := DontCare) 1252*c590fb32Scz4e 1253*c590fb32Scz4e 1254*c590fb32Scz4e // store prefetch train 1255*c590fb32Scz4e l1PrefetcherOpt.foreach(pf => { 1256*c590fb32Scz4e // stream will train on all load sources 1257*c590fb32Scz4e pf.io.st_in(i).valid := false.B 1258*c590fb32Scz4e pf.io.st_in(i).bits := DontCare 1259*c590fb32Scz4e }) 1260*c590fb32Scz4e 1261*c590fb32Scz4e prefetcherOpt.foreach(pf => { 1262*c590fb32Scz4e pf.io.st_in(i).valid := Mux(pf_train_on_hit, 1263*c590fb32Scz4e stu.io.prefetch_train.valid, 1264*c590fb32Scz4e stu.io.prefetch_train.valid && stu.io.prefetch_train.bits.isFirstIssue && ( 1265*c590fb32Scz4e stu.io.prefetch_train.bits.miss 1266*c590fb32Scz4e ) 1267*c590fb32Scz4e ) 1268*c590fb32Scz4e pf.io.st_in(i).bits := stu.io.prefetch_train.bits 1269*c590fb32Scz4e pf.io.st_in(i).bits.uop.pc := RegEnable(RegEnable(io.ooo_to_mem.storePc(i), stu.io.s1_prefetch_spec), stu.io.s2_prefetch_spec) 1270*c590fb32Scz4e }) 1271*c590fb32Scz4e 1272*c590fb32Scz4e // 1. sync issue info to store set LFST 1273*c590fb32Scz4e // 2. when store issue, broadcast issued sqPtr to wake up the following insts 1274*c590fb32Scz4e // io.stIn(i).valid := io.issue(exuParameters.LduCnt + i).valid 1275*c590fb32Scz4e // io.stIn(i).bits := io.issue(exuParameters.LduCnt + i).bits 1276*c590fb32Scz4e io.mem_to_ooo.stIn(i).valid := stu.io.issue.valid 1277*c590fb32Scz4e io.mem_to_ooo.stIn(i).bits := stu.io.issue.bits 1278*c590fb32Scz4e 1279*c590fb32Scz4e stu.io.stout.ready := true.B 1280*c590fb32Scz4e 1281*c590fb32Scz4e // vector 1282*c590fb32Scz4e if (i < VstuCnt) { 1283*c590fb32Scz4e stu.io.vecstin <> vsSplit(i).io.out 1284*c590fb32Scz4e // vsFlowQueue.io.pipeFeedback(i) <> stu.io.vec_feedback_slow // need connect 1285*c590fb32Scz4e } else { 1286*c590fb32Scz4e stu.io.vecstin.valid := false.B 1287*c590fb32Scz4e stu.io.vecstin.bits := DontCare 1288*c590fb32Scz4e stu.io.vecstout.ready := false.B 1289*c590fb32Scz4e } 1290*c590fb32Scz4e stu.io.vec_isFirstIssue := true.B // TODO 1291*c590fb32Scz4e } 1292*c590fb32Scz4e 1293*c590fb32Scz4e // mmio store writeback will use store writeback port 0 1294*c590fb32Scz4e val mmioStout = WireInit(0.U.asTypeOf(lsq.io.mmioStout)) 1295*c590fb32Scz4e NewPipelineConnect( 1296*c590fb32Scz4e lsq.io.mmioStout, mmioStout, mmioStout.fire, 1297*c590fb32Scz4e false.B, 1298*c590fb32Scz4e Option("mmioStOutConnect") 1299*c590fb32Scz4e ) 1300*c590fb32Scz4e mmioStout.ready := false.B 1301*c590fb32Scz4e when (mmioStout.valid && !storeUnits(0).io.stout.valid) { 1302*c590fb32Scz4e stOut(0).valid := true.B 1303*c590fb32Scz4e stOut(0).bits := mmioStout.bits 1304*c590fb32Scz4e mmioStout.ready := true.B 1305*c590fb32Scz4e } 1306*c590fb32Scz4e 1307*c590fb32Scz4e // vec mmio writeback 1308*c590fb32Scz4e lsq.io.vecmmioStout.ready := false.B 1309*c590fb32Scz4e 1310*c590fb32Scz4e // miss align buffer will overwrite stOut(0) 1311*c590fb32Scz4e val storeMisalignCanWriteBack = !mmioStout.valid && !storeUnits(0).io.stout.valid && !storeUnits(0).io.vecstout.valid 1312*c590fb32Scz4e storeMisalignBuffer.io.writeBack.ready := storeMisalignCanWriteBack 1313*c590fb32Scz4e storeMisalignBuffer.io.storeOutValid := storeUnits(0).io.stout.valid 1314*c590fb32Scz4e storeMisalignBuffer.io.storeVecOutValid := storeUnits(0).io.vecstout.valid 1315*c590fb32Scz4e when (storeMisalignBuffer.io.writeBack.valid && storeMisalignCanWriteBack) { 1316*c590fb32Scz4e stOut(0).valid := true.B 1317*c590fb32Scz4e stOut(0).bits := storeMisalignBuffer.io.writeBack.bits 1318*c590fb32Scz4e } 1319*c590fb32Scz4e 1320*c590fb32Scz4e // Uncache 1321*c590fb32Scz4e uncache.io.enableOutstanding := io.ooo_to_mem.csrCtrl.uncache_write_outstanding_enable 1322*c590fb32Scz4e uncache.io.hartId := io.hartId 1323*c590fb32Scz4e lsq.io.uncacheOutstanding := io.ooo_to_mem.csrCtrl.uncache_write_outstanding_enable 1324*c590fb32Scz4e 1325*c590fb32Scz4e // Lsq 1326*c590fb32Scz4e io.mem_to_ooo.lsqio.mmio := lsq.io.rob.mmio 1327*c590fb32Scz4e io.mem_to_ooo.lsqio.uop := lsq.io.rob.uop 1328*c590fb32Scz4e lsq.io.rob.lcommit := io.ooo_to_mem.lsqio.lcommit 1329*c590fb32Scz4e lsq.io.rob.scommit := io.ooo_to_mem.lsqio.scommit 1330*c590fb32Scz4e lsq.io.rob.pendingMMIOld := io.ooo_to_mem.lsqio.pendingMMIOld 1331*c590fb32Scz4e lsq.io.rob.pendingld := io.ooo_to_mem.lsqio.pendingld 1332*c590fb32Scz4e lsq.io.rob.pendingst := io.ooo_to_mem.lsqio.pendingst 1333*c590fb32Scz4e lsq.io.rob.pendingVst := io.ooo_to_mem.lsqio.pendingVst 1334*c590fb32Scz4e lsq.io.rob.commit := io.ooo_to_mem.lsqio.commit 1335*c590fb32Scz4e lsq.io.rob.pendingPtr := io.ooo_to_mem.lsqio.pendingPtr 1336*c590fb32Scz4e lsq.io.rob.pendingPtrNext := io.ooo_to_mem.lsqio.pendingPtrNext 1337*c590fb32Scz4e 1338*c590fb32Scz4e // lsq.io.rob <> io.lsqio.rob 1339*c590fb32Scz4e lsq.io.enq <> io.ooo_to_mem.enqLsq 1340*c590fb32Scz4e lsq.io.brqRedirect <> redirect 1341*c590fb32Scz4e 1342*c590fb32Scz4e // violation rollback 1343*c590fb32Scz4e def selectOldestRedirect(xs: Seq[Valid[Redirect]]): Vec[Bool] = { 1344*c590fb32Scz4e val compareVec = (0 until xs.length).map(i => (0 until i).map(j => isAfter(xs(j).bits.robIdx, xs(i).bits.robIdx))) 1345*c590fb32Scz4e val resultOnehot = VecInit((0 until xs.length).map(i => Cat((0 until xs.length).map(j => 1346*c590fb32Scz4e (if (j < i) !xs(j).valid || compareVec(i)(j) 1347*c590fb32Scz4e else if (j == i) xs(i).valid 1348*c590fb32Scz4e else !xs(j).valid || !compareVec(j)(i)) 1349*c590fb32Scz4e )).andR)) 1350*c590fb32Scz4e resultOnehot 1351*c590fb32Scz4e } 1352*c590fb32Scz4e val allRedirect = loadUnits.map(_.io.rollback) ++ hybridUnits.map(_.io.ldu_io.rollback) ++ lsq.io.nack_rollback ++ lsq.io.nuke_rollback 1353*c590fb32Scz4e val oldestOneHot = selectOldestRedirect(allRedirect) 1354*c590fb32Scz4e val oldestRedirect = WireDefault(Mux1H(oldestOneHot, allRedirect)) 1355*c590fb32Scz4e // memory replay would not cause IAF/IPF/IGPF 1356*c590fb32Scz4e oldestRedirect.bits.cfiUpdate.backendIAF := false.B 1357*c590fb32Scz4e oldestRedirect.bits.cfiUpdate.backendIPF := false.B 1358*c590fb32Scz4e oldestRedirect.bits.cfiUpdate.backendIGPF := false.B 1359*c590fb32Scz4e io.mem_to_ooo.memoryViolation := oldestRedirect 1360*c590fb32Scz4e io.mem_to_ooo.lsqio.lqCanAccept := lsq.io.lqCanAccept 1361*c590fb32Scz4e io.mem_to_ooo.lsqio.sqCanAccept := lsq.io.sqCanAccept 1362*c590fb32Scz4e 1363*c590fb32Scz4e // lsq.io.uncache <> uncache.io.lsq 1364*c590fb32Scz4e val s_idle :: s_scalar_uncache :: s_vector_uncache :: Nil = Enum(3) 1365*c590fb32Scz4e val uncacheState = RegInit(s_idle) 1366*c590fb32Scz4e val uncacheReq = Wire(Decoupled(new UncacheWordReq)) 1367*c590fb32Scz4e val uncacheIdResp = uncache.io.lsq.idResp 1368*c590fb32Scz4e val uncacheResp = Wire(Decoupled(new UncacheWordResp)) 1369*c590fb32Scz4e 1370*c590fb32Scz4e uncacheReq.bits := DontCare 1371*c590fb32Scz4e uncacheReq.valid := false.B 1372*c590fb32Scz4e uncacheReq.ready := false.B 1373*c590fb32Scz4e uncacheResp.bits := DontCare 1374*c590fb32Scz4e uncacheResp.valid := false.B 1375*c590fb32Scz4e uncacheResp.ready := false.B 1376*c590fb32Scz4e lsq.io.uncache.req.ready := false.B 1377*c590fb32Scz4e lsq.io.uncache.idResp.valid := false.B 1378*c590fb32Scz4e lsq.io.uncache.idResp.bits := DontCare 1379*c590fb32Scz4e lsq.io.uncache.resp.valid := false.B 1380*c590fb32Scz4e lsq.io.uncache.resp.bits := DontCare 1381*c590fb32Scz4e 1382*c590fb32Scz4e switch (uncacheState) { 1383*c590fb32Scz4e is (s_idle) { 1384*c590fb32Scz4e when (uncacheReq.fire) { 1385*c590fb32Scz4e when (lsq.io.uncache.req.valid) { 1386*c590fb32Scz4e when (!lsq.io.uncache.req.bits.nc || !io.ooo_to_mem.csrCtrl.uncache_write_outstanding_enable) { 1387*c590fb32Scz4e uncacheState := s_scalar_uncache 1388*c590fb32Scz4e } 1389*c590fb32Scz4e }.otherwise { 1390*c590fb32Scz4e // val isStore = vsFlowQueue.io.uncache.req.bits.cmd === MemoryOpConstants.M_XWR 1391*c590fb32Scz4e when (!io.ooo_to_mem.csrCtrl.uncache_write_outstanding_enable) { 1392*c590fb32Scz4e uncacheState := s_vector_uncache 1393*c590fb32Scz4e } 1394*c590fb32Scz4e } 1395*c590fb32Scz4e } 1396*c590fb32Scz4e } 1397*c590fb32Scz4e 1398*c590fb32Scz4e is (s_scalar_uncache) { 1399*c590fb32Scz4e when (uncacheResp.fire) { 1400*c590fb32Scz4e uncacheState := s_idle 1401*c590fb32Scz4e } 1402*c590fb32Scz4e } 1403*c590fb32Scz4e 1404*c590fb32Scz4e is (s_vector_uncache) { 1405*c590fb32Scz4e when (uncacheResp.fire) { 1406*c590fb32Scz4e uncacheState := s_idle 1407*c590fb32Scz4e } 1408*c590fb32Scz4e } 1409*c590fb32Scz4e } 1410*c590fb32Scz4e 1411*c590fb32Scz4e when (lsq.io.uncache.req.valid) { 1412*c590fb32Scz4e uncacheReq <> lsq.io.uncache.req 1413*c590fb32Scz4e } 1414*c590fb32Scz4e when (io.ooo_to_mem.csrCtrl.uncache_write_outstanding_enable) { 1415*c590fb32Scz4e lsq.io.uncache.resp <> uncacheResp 1416*c590fb32Scz4e lsq.io.uncache.idResp <> uncacheIdResp 1417*c590fb32Scz4e }.otherwise { 1418*c590fb32Scz4e when (uncacheState === s_scalar_uncache) { 1419*c590fb32Scz4e lsq.io.uncache.resp <> uncacheResp 1420*c590fb32Scz4e lsq.io.uncache.idResp <> uncacheIdResp 1421*c590fb32Scz4e } 1422*c590fb32Scz4e } 1423*c590fb32Scz4e // delay dcache refill for 1 cycle for better timing 1424*c590fb32Scz4e AddPipelineReg(uncacheReq, uncache.io.lsq.req, false.B) 1425*c590fb32Scz4e AddPipelineReg(uncache.io.lsq.resp, uncacheResp, false.B) 1426*c590fb32Scz4e 1427*c590fb32Scz4e //lsq.io.refill := delayedDcacheRefill 1428*c590fb32Scz4e lsq.io.release := dcache.io.lsu.release 1429*c590fb32Scz4e lsq.io.lqCancelCnt <> io.mem_to_ooo.lqCancelCnt 1430*c590fb32Scz4e lsq.io.sqCancelCnt <> io.mem_to_ooo.sqCancelCnt 1431*c590fb32Scz4e lsq.io.lqDeq <> io.mem_to_ooo.lqDeq 1432*c590fb32Scz4e lsq.io.sqDeq <> io.mem_to_ooo.sqDeq 1433*c590fb32Scz4e // Todo: assign these 1434*c590fb32Scz4e io.mem_to_ooo.sqDeqPtr := lsq.io.sqDeqPtr 1435*c590fb32Scz4e io.mem_to_ooo.lqDeqPtr := lsq.io.lqDeqPtr 1436*c590fb32Scz4e lsq.io.tl_d_channel <> dcache.io.lsu.tl_d_channel 1437*c590fb32Scz4e 1438*c590fb32Scz4e // LSQ to store buffer 1439*c590fb32Scz4e lsq.io.sbuffer <> sbuffer.io.in 1440*c590fb32Scz4e sbuffer.io.in(0).valid := lsq.io.sbuffer(0).valid || vSegmentUnit.io.sbuffer.valid 1441*c590fb32Scz4e sbuffer.io.in(0).bits := Mux1H(Seq( 1442*c590fb32Scz4e vSegmentUnit.io.sbuffer.valid -> vSegmentUnit.io.sbuffer.bits, 1443*c590fb32Scz4e lsq.io.sbuffer(0).valid -> lsq.io.sbuffer(0).bits 1444*c590fb32Scz4e )) 1445*c590fb32Scz4e vSegmentUnit.io.sbuffer.ready := sbuffer.io.in(0).ready 1446*c590fb32Scz4e lsq.io.sqEmpty <> sbuffer.io.sqempty 1447*c590fb32Scz4e dcache.io.force_write := lsq.io.force_write 1448*c590fb32Scz4e 1449*c590fb32Scz4e // Initialize when unenabled difftest. 1450*c590fb32Scz4e sbuffer.io.vecDifftestInfo := DontCare 1451*c590fb32Scz4e lsq.io.sbufferVecDifftestInfo := DontCare 1452*c590fb32Scz4e vSegmentUnit.io.vecDifftestInfo := DontCare 1453*c590fb32Scz4e if (env.EnableDifftest) { 1454*c590fb32Scz4e sbuffer.io.vecDifftestInfo .zipWithIndex.map{ case (sbufferPort, index) => 1455*c590fb32Scz4e if (index == 0) { 1456*c590fb32Scz4e val vSegmentDifftestValid = vSegmentUnit.io.vecDifftestInfo.valid 1457*c590fb32Scz4e sbufferPort.valid := Mux(vSegmentDifftestValid, vSegmentUnit.io.vecDifftestInfo.valid, lsq.io.sbufferVecDifftestInfo(0).valid) 1458*c590fb32Scz4e sbufferPort.bits := Mux(vSegmentDifftestValid, vSegmentUnit.io.vecDifftestInfo.bits, lsq.io.sbufferVecDifftestInfo(0).bits) 1459*c590fb32Scz4e 1460*c590fb32Scz4e vSegmentUnit.io.vecDifftestInfo.ready := sbufferPort.ready 1461*c590fb32Scz4e lsq.io.sbufferVecDifftestInfo(0).ready := sbufferPort.ready 1462*c590fb32Scz4e } else { 1463*c590fb32Scz4e sbufferPort <> lsq.io.sbufferVecDifftestInfo(index) 1464*c590fb32Scz4e } 1465*c590fb32Scz4e } 1466*c590fb32Scz4e } 1467*c590fb32Scz4e 1468*c590fb32Scz4e // lsq.io.vecStoreRetire <> vsFlowQueue.io.sqRelease 1469*c590fb32Scz4e // lsq.io.vecWriteback.valid := vlWrapper.io.uopWriteback.fire && 1470*c590fb32Scz4e // vlWrapper.io.uopWriteback.bits.uop.vpu.lastUop 1471*c590fb32Scz4e // lsq.io.vecWriteback.bits := vlWrapper.io.uopWriteback.bits 1472*c590fb32Scz4e 1473*c590fb32Scz4e // vector 1474*c590fb32Scz4e val vLoadCanAccept = (0 until VlduCnt).map(i => 1475*c590fb32Scz4e vlSplit(i).io.in.ready && VlduType.isVecLd(io.ooo_to_mem.issueVldu(i).bits.uop.fuOpType) 1476*c590fb32Scz4e ) 1477*c590fb32Scz4e val vStoreCanAccept = (0 until VstuCnt).map(i => 1478*c590fb32Scz4e vsSplit(i).io.in.ready && VstuType.isVecSt(io.ooo_to_mem.issueVldu(i).bits.uop.fuOpType) 1479*c590fb32Scz4e ) 1480*c590fb32Scz4e val isSegment = io.ooo_to_mem.issueVldu.head.valid && isVsegls(io.ooo_to_mem.issueVldu.head.bits.uop.fuType) 1481*c590fb32Scz4e val isFixVlUop = io.ooo_to_mem.issueVldu.map{x => 1482*c590fb32Scz4e x.bits.uop.vpu.isVleff && x.bits.uop.vpu.lastUop && x.valid 1483*c590fb32Scz4e } 1484*c590fb32Scz4e 1485*c590fb32Scz4e // init port 1486*c590fb32Scz4e /** 1487*c590fb32Scz4e * TODO: splited vsMergebuffer maybe remove, if one RS can accept two feedback, or don't need RS replay uop 1488*c590fb32Scz4e * for now: 1489*c590fb32Scz4e * RS0 -> VsSplit0 -> stu0 -> vsMergebuffer0 -> feedback -> RS0 1490*c590fb32Scz4e * RS1 -> VsSplit1 -> stu1 -> vsMergebuffer1 -> feedback -> RS1 1491*c590fb32Scz4e * 1492*c590fb32Scz4e * vector load don't need feedback 1493*c590fb32Scz4e * 1494*c590fb32Scz4e * RS0 -> VlSplit0 -> ldu0 -> | 1495*c590fb32Scz4e * RS1 -> VlSplit1 -> ldu1 -> | -> vlMergebuffer 1496*c590fb32Scz4e * replayIO -> ldu3 -> | 1497*c590fb32Scz4e * */ 1498*c590fb32Scz4e (0 until VstuCnt).foreach{i => 1499*c590fb32Scz4e vsMergeBuffer(i).io.fromPipeline := DontCare 1500*c590fb32Scz4e vsMergeBuffer(i).io.fromSplit := DontCare 1501*c590fb32Scz4e 1502*c590fb32Scz4e vsMergeBuffer(i).io.fromMisalignBuffer.get.flush := storeMisalignBuffer.io.toVecStoreMergeBuffer(i).flush 1503*c590fb32Scz4e vsMergeBuffer(i).io.fromMisalignBuffer.get.mbIndex := storeMisalignBuffer.io.toVecStoreMergeBuffer(i).mbIndex 1504*c590fb32Scz4e } 1505*c590fb32Scz4e 1506*c590fb32Scz4e (0 until VstuCnt).foreach{i => 1507*c590fb32Scz4e vsSplit(i).io.redirect <> redirect 1508*c590fb32Scz4e vsSplit(i).io.in <> io.ooo_to_mem.issueVldu(i) 1509*c590fb32Scz4e vsSplit(i).io.in.valid := io.ooo_to_mem.issueVldu(i).valid && 1510*c590fb32Scz4e vStoreCanAccept(i) && !isSegment 1511*c590fb32Scz4e vsSplit(i).io.toMergeBuffer <> vsMergeBuffer(i).io.fromSplit.head 1512*c590fb32Scz4e NewPipelineConnect( 1513*c590fb32Scz4e vsSplit(i).io.out, storeUnits(i).io.vecstin, storeUnits(i).io.vecstin.fire, 1514*c590fb32Scz4e Mux(vsSplit(i).io.out.fire, vsSplit(i).io.out.bits.uop.robIdx.needFlush(io.redirect), storeUnits(i).io.vecstin.bits.uop.robIdx.needFlush(io.redirect)), 1515*c590fb32Scz4e Option("VsSplitConnectStu") 1516*c590fb32Scz4e ) 1517*c590fb32Scz4e vsSplit(i).io.vstd.get := DontCare // Todo: Discuss how to pass vector store data 1518*c590fb32Scz4e 1519*c590fb32Scz4e vsSplit(i).io.vstdMisalign.get.storeMisalignBufferEmpty := !storeMisalignBuffer.io.full 1520*c590fb32Scz4e vsSplit(i).io.vstdMisalign.get.storePipeEmpty := !storeUnits(i).io.s0_s1_valid 1521*c590fb32Scz4e 1522*c590fb32Scz4e } 1523*c590fb32Scz4e (0 until VlduCnt).foreach{i => 1524*c590fb32Scz4e vlSplit(i).io.redirect <> redirect 1525*c590fb32Scz4e vlSplit(i).io.in <> io.ooo_to_mem.issueVldu(i) 1526*c590fb32Scz4e vlSplit(i).io.in.valid := io.ooo_to_mem.issueVldu(i).valid && 1527*c590fb32Scz4e vLoadCanAccept(i) && !isSegment && !isFixVlUop(i) 1528*c590fb32Scz4e vlSplit(i).io.toMergeBuffer <> vlMergeBuffer.io.fromSplit(i) 1529*c590fb32Scz4e vlSplit(i).io.threshold.get.valid := vlMergeBuffer.io.toSplit.get.threshold 1530*c590fb32Scz4e vlSplit(i).io.threshold.get.bits := lsq.io.lqDeqPtr 1531*c590fb32Scz4e NewPipelineConnect( 1532*c590fb32Scz4e vlSplit(i).io.out, loadUnits(i).io.vecldin, loadUnits(i).io.vecldin.fire, 1533*c590fb32Scz4e Mux(vlSplit(i).io.out.fire, vlSplit(i).io.out.bits.uop.robIdx.needFlush(io.redirect), loadUnits(i).io.vecldin.bits.uop.robIdx.needFlush(io.redirect)), 1534*c590fb32Scz4e Option("VlSplitConnectLdu") 1535*c590fb32Scz4e ) 1536*c590fb32Scz4e 1537*c590fb32Scz4e //Subsequent instrction will be blocked 1538*c590fb32Scz4e vfofBuffer.io.in(i).valid := io.ooo_to_mem.issueVldu(i).valid 1539*c590fb32Scz4e vfofBuffer.io.in(i).bits := io.ooo_to_mem.issueVldu(i).bits 1540*c590fb32Scz4e } 1541*c590fb32Scz4e (0 until LduCnt).foreach{i=> 1542*c590fb32Scz4e loadUnits(i).io.vecldout.ready := vlMergeBuffer.io.fromPipeline(i).ready 1543*c590fb32Scz4e loadMisalignBuffer.io.vecWriteBack.ready := true.B 1544*c590fb32Scz4e 1545*c590fb32Scz4e if (i == MisalignWBPort) { 1546*c590fb32Scz4e when(loadUnits(i).io.vecldout.valid) { 1547*c590fb32Scz4e vlMergeBuffer.io.fromPipeline(i).valid := loadUnits(i).io.vecldout.valid 1548*c590fb32Scz4e vlMergeBuffer.io.fromPipeline(i).bits := loadUnits(i).io.vecldout.bits 1549*c590fb32Scz4e } .otherwise { 1550*c590fb32Scz4e vlMergeBuffer.io.fromPipeline(i).valid := loadMisalignBuffer.io.vecWriteBack.valid 1551*c590fb32Scz4e vlMergeBuffer.io.fromPipeline(i).bits := loadMisalignBuffer.io.vecWriteBack.bits 1552*c590fb32Scz4e } 1553*c590fb32Scz4e } else { 1554*c590fb32Scz4e vlMergeBuffer.io.fromPipeline(i).valid := loadUnits(i).io.vecldout.valid 1555*c590fb32Scz4e vlMergeBuffer.io.fromPipeline(i).bits := loadUnits(i).io.vecldout.bits 1556*c590fb32Scz4e } 1557*c590fb32Scz4e } 1558*c590fb32Scz4e 1559*c590fb32Scz4e (0 until StaCnt).foreach{i=> 1560*c590fb32Scz4e if(i < VstuCnt){ 1561*c590fb32Scz4e storeUnits(i).io.vecstout.ready := true.B 1562*c590fb32Scz4e storeMisalignBuffer.io.vecWriteBack(i).ready := vsMergeBuffer(i).io.fromPipeline.head.ready 1563*c590fb32Scz4e 1564*c590fb32Scz4e when(storeUnits(i).io.vecstout.valid) { 1565*c590fb32Scz4e vsMergeBuffer(i).io.fromPipeline.head.valid := storeUnits(i).io.vecstout.valid 1566*c590fb32Scz4e vsMergeBuffer(i).io.fromPipeline.head.bits := storeUnits(i).io.vecstout.bits 1567*c590fb32Scz4e } .otherwise { 1568*c590fb32Scz4e vsMergeBuffer(i).io.fromPipeline.head.valid := storeMisalignBuffer.io.vecWriteBack(i).valid 1569*c590fb32Scz4e vsMergeBuffer(i).io.fromPipeline.head.bits := storeMisalignBuffer.io.vecWriteBack(i).bits 1570*c590fb32Scz4e } 1571*c590fb32Scz4e } 1572*c590fb32Scz4e } 1573*c590fb32Scz4e 1574*c590fb32Scz4e (0 until VlduCnt).foreach{i=> 1575*c590fb32Scz4e io.ooo_to_mem.issueVldu(i).ready := vLoadCanAccept(i) || vStoreCanAccept(i) 1576*c590fb32Scz4e } 1577*c590fb32Scz4e 1578*c590fb32Scz4e vlMergeBuffer.io.redirect <> redirect 1579*c590fb32Scz4e vsMergeBuffer.map(_.io.redirect <> redirect) 1580*c590fb32Scz4e (0 until VlduCnt).foreach{i=> 1581*c590fb32Scz4e vlMergeBuffer.io.toLsq(i) <> lsq.io.ldvecFeedback(i) 1582*c590fb32Scz4e } 1583*c590fb32Scz4e (0 until VstuCnt).foreach{i=> 1584*c590fb32Scz4e vsMergeBuffer(i).io.toLsq.head <> lsq.io.stvecFeedback(i) 1585*c590fb32Scz4e } 1586*c590fb32Scz4e 1587*c590fb32Scz4e (0 until VlduCnt).foreach{i=> 1588*c590fb32Scz4e // send to RS 1589*c590fb32Scz4e vlMergeBuffer.io.feedback(i) <> io.mem_to_ooo.vlduIqFeedback(i).feedbackSlow 1590*c590fb32Scz4e io.mem_to_ooo.vlduIqFeedback(i).feedbackFast := DontCare 1591*c590fb32Scz4e } 1592*c590fb32Scz4e (0 until VstuCnt).foreach{i => 1593*c590fb32Scz4e // send to RS 1594*c590fb32Scz4e if (i == 0){ 1595*c590fb32Scz4e io.mem_to_ooo.vstuIqFeedback(i).feedbackSlow.valid := vsMergeBuffer(i).io.feedback.head.valid || vSegmentUnit.io.feedback.valid 1596*c590fb32Scz4e io.mem_to_ooo.vstuIqFeedback(i).feedbackSlow.bits := Mux1H(Seq( 1597*c590fb32Scz4e vSegmentUnit.io.feedback.valid -> vSegmentUnit.io.feedback.bits, 1598*c590fb32Scz4e vsMergeBuffer(i).io.feedback.head.valid -> vsMergeBuffer(i).io.feedback.head.bits 1599*c590fb32Scz4e )) 1600*c590fb32Scz4e io.mem_to_ooo.vstuIqFeedback(i).feedbackFast := DontCare 1601*c590fb32Scz4e } else { 1602*c590fb32Scz4e vsMergeBuffer(i).io.feedback.head <> io.mem_to_ooo.vstuIqFeedback(i).feedbackSlow 1603*c590fb32Scz4e io.mem_to_ooo.vstuIqFeedback(i).feedbackFast := DontCare 1604*c590fb32Scz4e } 1605*c590fb32Scz4e } 1606*c590fb32Scz4e 1607*c590fb32Scz4e (0 until VlduCnt).foreach{i=> 1608*c590fb32Scz4e if (i == 0){ // for segmentUnit, segmentUnit use port0 writeback 1609*c590fb32Scz4e io.mem_to_ooo.writebackVldu(i).valid := vlMergeBuffer.io.uopWriteback(i).valid || vsMergeBuffer(i).io.uopWriteback.head.valid || vSegmentUnit.io.uopwriteback.valid 1610*c590fb32Scz4e io.mem_to_ooo.writebackVldu(i).bits := PriorityMux(Seq( 1611*c590fb32Scz4e vSegmentUnit.io.uopwriteback.valid -> vSegmentUnit.io.uopwriteback.bits, 1612*c590fb32Scz4e vlMergeBuffer.io.uopWriteback(i).valid -> vlMergeBuffer.io.uopWriteback(i).bits, 1613*c590fb32Scz4e vsMergeBuffer(i).io.uopWriteback.head.valid -> vsMergeBuffer(i).io.uopWriteback.head.bits, 1614*c590fb32Scz4e )) 1615*c590fb32Scz4e vlMergeBuffer.io.uopWriteback(i).ready := io.mem_to_ooo.writebackVldu(i).ready && !vSegmentUnit.io.uopwriteback.valid 1616*c590fb32Scz4e vsMergeBuffer(i).io.uopWriteback.head.ready := io.mem_to_ooo.writebackVldu(i).ready && !vlMergeBuffer.io.uopWriteback(i).valid && !vSegmentUnit.io.uopwriteback.valid 1617*c590fb32Scz4e vSegmentUnit.io.uopwriteback.ready := io.mem_to_ooo.writebackVldu(i).ready 1618*c590fb32Scz4e } else if (i == 1) { 1619*c590fb32Scz4e io.mem_to_ooo.writebackVldu(i).valid := vlMergeBuffer.io.uopWriteback(i).valid || vsMergeBuffer(i).io.uopWriteback.head.valid || vfofBuffer.io.uopWriteback.valid 1620*c590fb32Scz4e io.mem_to_ooo.writebackVldu(i).bits := PriorityMux(Seq( 1621*c590fb32Scz4e vfofBuffer.io.uopWriteback.valid -> vfofBuffer.io.uopWriteback.bits, 1622*c590fb32Scz4e vlMergeBuffer.io.uopWriteback(i).valid -> vlMergeBuffer.io.uopWriteback(i).bits, 1623*c590fb32Scz4e vsMergeBuffer(i).io.uopWriteback.head.valid -> vsMergeBuffer(i).io.uopWriteback.head.bits, 1624*c590fb32Scz4e )) 1625*c590fb32Scz4e vlMergeBuffer.io.uopWriteback(i).ready := io.mem_to_ooo.writebackVldu(i).ready && !vfofBuffer.io.uopWriteback.valid 1626*c590fb32Scz4e vsMergeBuffer(i).io.uopWriteback.head.ready := io.mem_to_ooo.writebackVldu(i).ready && !vlMergeBuffer.io.uopWriteback(i).valid && !vfofBuffer.io.uopWriteback.valid 1627*c590fb32Scz4e vfofBuffer.io.uopWriteback.ready := io.mem_to_ooo.writebackVldu(i).ready 1628*c590fb32Scz4e } else { 1629*c590fb32Scz4e io.mem_to_ooo.writebackVldu(i).valid := vlMergeBuffer.io.uopWriteback(i).valid || vsMergeBuffer(i).io.uopWriteback.head.valid 1630*c590fb32Scz4e io.mem_to_ooo.writebackVldu(i).bits := PriorityMux(Seq( 1631*c590fb32Scz4e vlMergeBuffer.io.uopWriteback(i).valid -> vlMergeBuffer.io.uopWriteback(i).bits, 1632*c590fb32Scz4e vsMergeBuffer(i).io.uopWriteback.head.valid -> vsMergeBuffer(i).io.uopWriteback.head.bits, 1633*c590fb32Scz4e )) 1634*c590fb32Scz4e vlMergeBuffer.io.uopWriteback(i).ready := io.mem_to_ooo.writebackVldu(i).ready 1635*c590fb32Scz4e vsMergeBuffer(i).io.uopWriteback.head.ready := io.mem_to_ooo.writebackVldu(i).ready && !vlMergeBuffer.io.uopWriteback(i).valid 1636*c590fb32Scz4e } 1637*c590fb32Scz4e 1638*c590fb32Scz4e vfofBuffer.io.mergeUopWriteback(i).valid := vlMergeBuffer.io.uopWriteback(i).valid 1639*c590fb32Scz4e vfofBuffer.io.mergeUopWriteback(i).bits := vlMergeBuffer.io.uopWriteback(i).bits 1640*c590fb32Scz4e } 1641*c590fb32Scz4e 1642*c590fb32Scz4e 1643*c590fb32Scz4e vfofBuffer.io.redirect <> redirect 1644*c590fb32Scz4e 1645*c590fb32Scz4e // Sbuffer 1646*c590fb32Scz4e sbuffer.io.csrCtrl <> csrCtrl 1647*c590fb32Scz4e sbuffer.io.dcache <> dcache.io.lsu.store 1648*c590fb32Scz4e sbuffer.io.memSetPattenDetected := dcache.io.memSetPattenDetected 1649*c590fb32Scz4e sbuffer.io.force_write <> lsq.io.force_write 1650*c590fb32Scz4e // flush sbuffer 1651*c590fb32Scz4e val cmoFlush = lsq.io.flushSbuffer.valid 1652*c590fb32Scz4e val fenceFlush = io.ooo_to_mem.flushSb 1653*c590fb32Scz4e val atomicsFlush = atomicsUnit.io.flush_sbuffer.valid || vSegmentUnit.io.flush_sbuffer.valid 1654*c590fb32Scz4e val stIsEmpty = sbuffer.io.flush.empty && uncache.io.flush.empty 1655*c590fb32Scz4e io.mem_to_ooo.sbIsEmpty := RegNext(stIsEmpty) 1656*c590fb32Scz4e 1657*c590fb32Scz4e // if both of them tries to flush sbuffer at the same time 1658*c590fb32Scz4e // something must have gone wrong 1659*c590fb32Scz4e assert(!(fenceFlush && atomicsFlush && cmoFlush)) 1660*c590fb32Scz4e sbuffer.io.flush.valid := RegNext(fenceFlush || atomicsFlush || cmoFlush) 1661*c590fb32Scz4e uncache.io.flush.valid := sbuffer.io.flush.valid 1662*c590fb32Scz4e 1663*c590fb32Scz4e // AtomicsUnit: AtomicsUnit will override other control signials, 1664*c590fb32Scz4e // as atomics insts (LR/SC/AMO) will block the pipeline 1665*c590fb32Scz4e val s_normal +: s_atomics = Enum(StaCnt + HyuCnt + 1) 1666*c590fb32Scz4e val state = RegInit(s_normal) 1667*c590fb32Scz4e 1668*c590fb32Scz4e val st_atomics = Seq.tabulate(StaCnt)(i => 1669*c590fb32Scz4e io.ooo_to_mem.issueSta(i).valid && FuType.storeIsAMO((io.ooo_to_mem.issueSta(i).bits.uop.fuType)) 1670*c590fb32Scz4e ) ++ Seq.tabulate(HyuCnt)(i => 1671*c590fb32Scz4e io.ooo_to_mem.issueHya(i).valid && FuType.storeIsAMO((io.ooo_to_mem.issueHya(i).bits.uop.fuType)) 1672*c590fb32Scz4e ) 1673*c590fb32Scz4e 1674*c590fb32Scz4e for (i <- 0 until StaCnt) when(st_atomics(i)) { 1675*c590fb32Scz4e io.ooo_to_mem.issueSta(i).ready := atomicsUnit.io.in.ready 1676*c590fb32Scz4e storeUnits(i).io.stin.valid := false.B 1677*c590fb32Scz4e 1678*c590fb32Scz4e state := s_atomics(i) 1679*c590fb32Scz4e } 1680*c590fb32Scz4e for (i <- 0 until HyuCnt) when(st_atomics(StaCnt + i)) { 1681*c590fb32Scz4e io.ooo_to_mem.issueHya(i).ready := atomicsUnit.io.in.ready 1682*c590fb32Scz4e hybridUnits(i).io.lsin.valid := false.B 1683*c590fb32Scz4e 1684*c590fb32Scz4e state := s_atomics(StaCnt + i) 1685*c590fb32Scz4e assert(!st_atomics.zipWithIndex.filterNot(_._2 == StaCnt + i).unzip._1.reduce(_ || _)) 1686*c590fb32Scz4e } 1687*c590fb32Scz4e when (atomicsUnit.io.out.valid) { 1688*c590fb32Scz4e state := s_normal 1689*c590fb32Scz4e } 1690*c590fb32Scz4e 1691*c590fb32Scz4e atomicsUnit.io.in.valid := st_atomics.reduce(_ || _) 1692*c590fb32Scz4e atomicsUnit.io.in.bits := Mux1H(Seq.tabulate(StaCnt)(i => 1693*c590fb32Scz4e st_atomics(i) -> io.ooo_to_mem.issueSta(i).bits) ++ 1694*c590fb32Scz4e Seq.tabulate(HyuCnt)(i => st_atomics(StaCnt+i) -> io.ooo_to_mem.issueHya(i).bits)) 1695*c590fb32Scz4e atomicsUnit.io.storeDataIn.zipWithIndex.foreach { case (stdin, i) => 1696*c590fb32Scz4e stdin.valid := st_data_atomics(i) 1697*c590fb32Scz4e stdin.bits := stData(i).bits 1698*c590fb32Scz4e } 1699*c590fb32Scz4e atomicsUnit.io.redirect <> redirect 1700*c590fb32Scz4e 1701*c590fb32Scz4e // TODO: complete amo's pmp support 1702*c590fb32Scz4e val amoTlb = dtlb_ld(0).requestor(0) 1703*c590fb32Scz4e atomicsUnit.io.dtlb.resp.valid := false.B 1704*c590fb32Scz4e atomicsUnit.io.dtlb.resp.bits := DontCare 1705*c590fb32Scz4e atomicsUnit.io.dtlb.req.ready := amoTlb.req.ready 1706*c590fb32Scz4e atomicsUnit.io.pmpResp := pmp_check(0).resp 1707*c590fb32Scz4e 1708*c590fb32Scz4e atomicsUnit.io.dcache <> dcache.io.lsu.atomics 1709*c590fb32Scz4e atomicsUnit.io.flush_sbuffer.empty := stIsEmpty 1710*c590fb32Scz4e 1711*c590fb32Scz4e atomicsUnit.io.csrCtrl := csrCtrl 1712*c590fb32Scz4e 1713*c590fb32Scz4e // for atomicsUnit, it uses loadUnit(0)'s TLB port 1714*c590fb32Scz4e 1715*c590fb32Scz4e when (state =/= s_normal) { 1716*c590fb32Scz4e // use store wb port instead of load 1717*c590fb32Scz4e loadUnits(0).io.ldout.ready := false.B 1718*c590fb32Scz4e // use load_0's TLB 1719*c590fb32Scz4e atomicsUnit.io.dtlb <> amoTlb 1720*c590fb32Scz4e 1721*c590fb32Scz4e // hw prefetch should be disabled while executing atomic insts 1722*c590fb32Scz4e loadUnits.map(i => i.io.prefetch_req.valid := false.B) 1723*c590fb32Scz4e 1724*c590fb32Scz4e // make sure there's no in-flight uops in load unit 1725*c590fb32Scz4e assert(!loadUnits(0).io.ldout.valid) 1726*c590fb32Scz4e } 1727*c590fb32Scz4e 1728*c590fb32Scz4e lsq.io.flushSbuffer.empty := sbuffer.io.sbempty 1729*c590fb32Scz4e 1730*c590fb32Scz4e for (i <- 0 until StaCnt) { 1731*c590fb32Scz4e when (state === s_atomics(i)) { 1732*c590fb32Scz4e io.mem_to_ooo.staIqFeedback(i).feedbackSlow := atomicsUnit.io.feedbackSlow 1733*c590fb32Scz4e assert(!storeUnits(i).io.feedback_slow.valid) 1734*c590fb32Scz4e } 1735*c590fb32Scz4e } 1736*c590fb32Scz4e for (i <- 0 until HyuCnt) { 1737*c590fb32Scz4e when (state === s_atomics(StaCnt + i)) { 1738*c590fb32Scz4e io.mem_to_ooo.hyuIqFeedback(i).feedbackSlow := atomicsUnit.io.feedbackSlow 1739*c590fb32Scz4e assert(!hybridUnits(i).io.feedback_slow.valid) 1740*c590fb32Scz4e } 1741*c590fb32Scz4e } 1742*c590fb32Scz4e 1743*c590fb32Scz4e lsq.io.exceptionAddr.isStore := io.ooo_to_mem.isStoreException 1744*c590fb32Scz4e // Exception address is used several cycles after flush. 1745*c590fb32Scz4e // We delay it by 10 cycles to ensure its flush safety. 1746*c590fb32Scz4e val atomicsException = RegInit(false.B) 1747*c590fb32Scz4e when (DelayN(redirect.valid, 10) && atomicsException) { 1748*c590fb32Scz4e atomicsException := false.B 1749*c590fb32Scz4e }.elsewhen (atomicsUnit.io.exceptionInfo.valid) { 1750*c590fb32Scz4e atomicsException := true.B 1751*c590fb32Scz4e } 1752*c590fb32Scz4e 1753*c590fb32Scz4e val misalignBufExceptionOverwrite = loadMisalignBuffer.io.overwriteExpBuf.valid || storeMisalignBuffer.io.overwriteExpBuf.valid 1754*c590fb32Scz4e val misalignBufExceptionVaddr = Mux(loadMisalignBuffer.io.overwriteExpBuf.valid, 1755*c590fb32Scz4e loadMisalignBuffer.io.overwriteExpBuf.vaddr, 1756*c590fb32Scz4e storeMisalignBuffer.io.overwriteExpBuf.vaddr 1757*c590fb32Scz4e ) 1758*c590fb32Scz4e val misalignBufExceptionIsHyper = Mux(loadMisalignBuffer.io.overwriteExpBuf.valid, 1759*c590fb32Scz4e loadMisalignBuffer.io.overwriteExpBuf.isHyper, 1760*c590fb32Scz4e storeMisalignBuffer.io.overwriteExpBuf.isHyper 1761*c590fb32Scz4e ) 1762*c590fb32Scz4e val misalignBufExceptionGpaddr = Mux(loadMisalignBuffer.io.overwriteExpBuf.valid, 1763*c590fb32Scz4e loadMisalignBuffer.io.overwriteExpBuf.gpaddr, 1764*c590fb32Scz4e storeMisalignBuffer.io.overwriteExpBuf.gpaddr 1765*c590fb32Scz4e ) 1766*c590fb32Scz4e val misalignBufExceptionIsForVSnonLeafPTE = Mux(loadMisalignBuffer.io.overwriteExpBuf.valid, 1767*c590fb32Scz4e loadMisalignBuffer.io.overwriteExpBuf.isForVSnonLeafPTE, 1768*c590fb32Scz4e storeMisalignBuffer.io.overwriteExpBuf.isForVSnonLeafPTE 1769*c590fb32Scz4e ) 1770*c590fb32Scz4e 1771*c590fb32Scz4e val vSegmentException = RegInit(false.B) 1772*c590fb32Scz4e when (DelayN(redirect.valid, 10) && vSegmentException) { 1773*c590fb32Scz4e vSegmentException := false.B 1774*c590fb32Scz4e }.elsewhen (vSegmentUnit.io.exceptionInfo.valid) { 1775*c590fb32Scz4e vSegmentException := true.B 1776*c590fb32Scz4e } 1777*c590fb32Scz4e val atomicsExceptionAddress = RegEnable(atomicsUnit.io.exceptionInfo.bits.vaddr, atomicsUnit.io.exceptionInfo.valid) 1778*c590fb32Scz4e val vSegmentExceptionVstart = RegEnable(vSegmentUnit.io.exceptionInfo.bits.vstart, vSegmentUnit.io.exceptionInfo.valid) 1779*c590fb32Scz4e val vSegmentExceptionVl = RegEnable(vSegmentUnit.io.exceptionInfo.bits.vl, vSegmentUnit.io.exceptionInfo.valid) 1780*c590fb32Scz4e val vSegmentExceptionAddress = RegEnable(vSegmentUnit.io.exceptionInfo.bits.vaddr, vSegmentUnit.io.exceptionInfo.valid) 1781*c590fb32Scz4e val atomicsExceptionGPAddress = RegEnable(atomicsUnit.io.exceptionInfo.bits.gpaddr, atomicsUnit.io.exceptionInfo.valid) 1782*c590fb32Scz4e val vSegmentExceptionGPAddress = RegEnable(vSegmentUnit.io.exceptionInfo.bits.gpaddr, vSegmentUnit.io.exceptionInfo.valid) 1783*c590fb32Scz4e val atomicsExceptionIsForVSnonLeafPTE = RegEnable(atomicsUnit.io.exceptionInfo.bits.isForVSnonLeafPTE, atomicsUnit.io.exceptionInfo.valid) 1784*c590fb32Scz4e val vSegmentExceptionIsForVSnonLeafPTE = RegEnable(vSegmentUnit.io.exceptionInfo.bits.isForVSnonLeafPTE, vSegmentUnit.io.exceptionInfo.valid) 1785*c590fb32Scz4e 1786*c590fb32Scz4e val exceptionVaddr = Mux( 1787*c590fb32Scz4e atomicsException, 1788*c590fb32Scz4e atomicsExceptionAddress, 1789*c590fb32Scz4e Mux(misalignBufExceptionOverwrite, 1790*c590fb32Scz4e misalignBufExceptionVaddr, 1791*c590fb32Scz4e Mux(vSegmentException, 1792*c590fb32Scz4e vSegmentExceptionAddress, 1793*c590fb32Scz4e lsq.io.exceptionAddr.vaddr 1794*c590fb32Scz4e ) 1795*c590fb32Scz4e ) 1796*c590fb32Scz4e ) 1797*c590fb32Scz4e // whether vaddr need ext or is hyper inst: 1798*c590fb32Scz4e // VaNeedExt: atomicsException -> false; misalignBufExceptionOverwrite -> true; vSegmentException -> false 1799*c590fb32Scz4e // IsHyper: atomicsException -> false; vSegmentException -> false 1800*c590fb32Scz4e val exceptionVaNeedExt = !atomicsException && 1801*c590fb32Scz4e (misalignBufExceptionOverwrite || 1802*c590fb32Scz4e (!vSegmentException && lsq.io.exceptionAddr.vaNeedExt)) 1803*c590fb32Scz4e val exceptionIsHyper = !atomicsException && 1804*c590fb32Scz4e (misalignBufExceptionOverwrite && misalignBufExceptionIsHyper || 1805*c590fb32Scz4e (!vSegmentException && lsq.io.exceptionAddr.isHyper && !misalignBufExceptionOverwrite)) 1806*c590fb32Scz4e 1807*c590fb32Scz4e def GenExceptionVa(mode: UInt, isVirt: Bool, vaNeedExt: Bool, 1808*c590fb32Scz4e satp: TlbSatpBundle, vsatp: TlbSatpBundle, hgatp: TlbHgatpBundle, 1809*c590fb32Scz4e vaddr: UInt) = { 1810*c590fb32Scz4e require(VAddrBits >= 50) 1811*c590fb32Scz4e 1812*c590fb32Scz4e val Sv39 = satp.mode === 8.U 1813*c590fb32Scz4e val Sv48 = satp.mode === 9.U 1814*c590fb32Scz4e val Sv39x4 = vsatp.mode === 8.U || hgatp.mode === 8.U 1815*c590fb32Scz4e val Sv48x4 = vsatp.mode === 9.U || hgatp.mode === 9.U 1816*c590fb32Scz4e val vmEnable = !isVirt && (Sv39 || Sv48) && (mode < ModeM) 1817*c590fb32Scz4e val s2xlateEnable = isVirt && (Sv39x4 || Sv48x4) && (mode < ModeM) 1818*c590fb32Scz4e 1819*c590fb32Scz4e val s2xlate = MuxCase(noS2xlate, Seq( 1820*c590fb32Scz4e !isVirt -> noS2xlate, 1821*c590fb32Scz4e (vsatp.mode =/= 0.U && hgatp.mode =/= 0.U) -> allStage, 1822*c590fb32Scz4e (vsatp.mode === 0.U) -> onlyStage2, 1823*c590fb32Scz4e (hgatp.mode === 0.U) -> onlyStage1 1824*c590fb32Scz4e )) 1825*c590fb32Scz4e val onlyS2 = s2xlate === onlyStage2 1826*c590fb32Scz4e 1827*c590fb32Scz4e val bareAddr = ZeroExt(vaddr(PAddrBits - 1, 0), XLEN) 1828*c590fb32Scz4e val sv39Addr = SignExt(vaddr.take(39), XLEN) 1829*c590fb32Scz4e val sv39x4Addr = ZeroExt(vaddr.take(39 + 2), XLEN) 1830*c590fb32Scz4e val sv48Addr = SignExt(vaddr.take(48), XLEN) 1831*c590fb32Scz4e val sv48x4Addr = ZeroExt(vaddr.take(48 + 2), XLEN) 1832*c590fb32Scz4e 1833*c590fb32Scz4e val ExceptionVa = Wire(UInt(XLEN.W)) 1834*c590fb32Scz4e when (vaNeedExt) { 1835*c590fb32Scz4e ExceptionVa := Mux1H(Seq( 1836*c590fb32Scz4e (!(vmEnable || s2xlateEnable)) -> bareAddr, 1837*c590fb32Scz4e (!onlyS2 && (Sv39 || Sv39x4)) -> sv39Addr, 1838*c590fb32Scz4e (!onlyS2 && (Sv48 || Sv48x4)) -> sv48Addr, 1839*c590fb32Scz4e ( onlyS2 && (Sv39 || Sv39x4)) -> sv39x4Addr, 1840*c590fb32Scz4e ( onlyS2 && (Sv48 || Sv48x4)) -> sv48x4Addr, 1841*c590fb32Scz4e )) 1842*c590fb32Scz4e } .otherwise { 1843*c590fb32Scz4e ExceptionVa := vaddr 1844*c590fb32Scz4e } 1845*c590fb32Scz4e 1846*c590fb32Scz4e ExceptionVa 1847*c590fb32Scz4e } 1848*c590fb32Scz4e 1849*c590fb32Scz4e io.mem_to_ooo.lsqio.vaddr := RegNext( 1850*c590fb32Scz4e GenExceptionVa(tlbcsr.priv.dmode, tlbcsr.priv.virt || exceptionIsHyper, exceptionVaNeedExt, 1851*c590fb32Scz4e tlbcsr.satp, tlbcsr.vsatp, tlbcsr.hgatp, exceptionVaddr) 1852*c590fb32Scz4e ) 1853*c590fb32Scz4e 1854*c590fb32Scz4e // vsegment instruction is executed atomic, which mean atomicsException and vSegmentException should not raise at the same time. 1855*c590fb32Scz4e XSError(atomicsException && vSegmentException, "atomicsException and vSegmentException raise at the same time!") 1856*c590fb32Scz4e io.mem_to_ooo.lsqio.vstart := RegNext(Mux(vSegmentException, 1857*c590fb32Scz4e vSegmentExceptionVstart, 1858*c590fb32Scz4e lsq.io.exceptionAddr.vstart) 1859*c590fb32Scz4e ) 1860*c590fb32Scz4e io.mem_to_ooo.lsqio.vl := RegNext(Mux(vSegmentException, 1861*c590fb32Scz4e vSegmentExceptionVl, 1862*c590fb32Scz4e lsq.io.exceptionAddr.vl) 1863*c590fb32Scz4e ) 1864*c590fb32Scz4e 1865*c590fb32Scz4e XSError(atomicsException && atomicsUnit.io.in.valid, "new instruction before exception triggers\n") 1866*c590fb32Scz4e io.mem_to_ooo.lsqio.gpaddr := RegNext(Mux( 1867*c590fb32Scz4e atomicsException, 1868*c590fb32Scz4e atomicsExceptionGPAddress, 1869*c590fb32Scz4e Mux(misalignBufExceptionOverwrite, 1870*c590fb32Scz4e misalignBufExceptionGpaddr, 1871*c590fb32Scz4e Mux(vSegmentException, 1872*c590fb32Scz4e vSegmentExceptionGPAddress, 1873*c590fb32Scz4e lsq.io.exceptionAddr.gpaddr 1874*c590fb32Scz4e ) 1875*c590fb32Scz4e ) 1876*c590fb32Scz4e )) 1877*c590fb32Scz4e io.mem_to_ooo.lsqio.isForVSnonLeafPTE := RegNext(Mux( 1878*c590fb32Scz4e atomicsException, 1879*c590fb32Scz4e atomicsExceptionIsForVSnonLeafPTE, 1880*c590fb32Scz4e Mux(misalignBufExceptionOverwrite, 1881*c590fb32Scz4e misalignBufExceptionIsForVSnonLeafPTE, 1882*c590fb32Scz4e Mux(vSegmentException, 1883*c590fb32Scz4e vSegmentExceptionIsForVSnonLeafPTE, 1884*c590fb32Scz4e lsq.io.exceptionAddr.isForVSnonLeafPTE 1885*c590fb32Scz4e ) 1886*c590fb32Scz4e ) 1887*c590fb32Scz4e )) 1888*c590fb32Scz4e io.mem_to_ooo.topToBackendBypass match { case x => 1889*c590fb32Scz4e x.hartId := io.hartId 1890*c590fb32Scz4e x.l2FlushDone := RegNext(io.l2_flush_done) 1891*c590fb32Scz4e x.externalInterrupt.msip := outer.clint_int_sink.in.head._1(0) 1892*c590fb32Scz4e x.externalInterrupt.mtip := outer.clint_int_sink.in.head._1(1) 1893*c590fb32Scz4e x.externalInterrupt.meip := outer.plic_int_sink.in.head._1(0) 1894*c590fb32Scz4e x.externalInterrupt.seip := outer.plic_int_sink.in.last._1(0) 1895*c590fb32Scz4e x.externalInterrupt.debug := outer.debug_int_sink.in.head._1(0) 1896*c590fb32Scz4e x.externalInterrupt.nmi.nmi_31 := outer.nmi_int_sink.in.head._1(0) 1897*c590fb32Scz4e x.externalInterrupt.nmi.nmi_43 := outer.nmi_int_sink.in.head._1(1) 1898*c590fb32Scz4e x.msiInfo := DelayNWithValid(io.fromTopToBackend.msiInfo, 1) 1899*c590fb32Scz4e x.clintTime := DelayNWithValid(io.fromTopToBackend.clintTime, 1) 1900*c590fb32Scz4e } 1901*c590fb32Scz4e 1902*c590fb32Scz4e io.memInfo.sqFull := RegNext(lsq.io.sqFull) 1903*c590fb32Scz4e io.memInfo.lqFull := RegNext(lsq.io.lqFull) 1904*c590fb32Scz4e io.memInfo.dcacheMSHRFull := RegNext(dcache.io.mshrFull) 1905*c590fb32Scz4e 1906*c590fb32Scz4e io.inner_hartId := io.hartId 1907*c590fb32Scz4e io.inner_reset_vector := RegNext(io.outer_reset_vector) 1908*c590fb32Scz4e io.outer_cpu_halt := io.ooo_to_mem.backendToTopBypass.cpuHalted 1909*c590fb32Scz4e io.outer_l2_flush_en := io.ooo_to_mem.csrCtrl.flush_l2_enable 1910*c590fb32Scz4e io.outer_power_down_en := io.ooo_to_mem.csrCtrl.power_down_enable 1911*c590fb32Scz4e io.outer_cpu_critical_error := io.ooo_to_mem.backendToTopBypass.cpuCriticalError 1912*c590fb32Scz4e io.outer_beu_errors_icache := RegNext(io.inner_beu_errors_icache) 1913*c590fb32Scz4e io.inner_hc_perfEvents <> RegNext(io.outer_hc_perfEvents) 1914*c590fb32Scz4e 1915*c590fb32Scz4e // vector segmentUnit 1916*c590fb32Scz4e vSegmentUnit.io.in.bits <> io.ooo_to_mem.issueVldu.head.bits 1917*c590fb32Scz4e vSegmentUnit.io.in.valid := isSegment && io.ooo_to_mem.issueVldu.head.valid// is segment instruction 1918*c590fb32Scz4e vSegmentUnit.io.dtlb.resp.bits <> dtlb_reqs.take(LduCnt).head.resp.bits 1919*c590fb32Scz4e vSegmentUnit.io.dtlb.resp.valid <> dtlb_reqs.take(LduCnt).head.resp.valid 1920*c590fb32Scz4e vSegmentUnit.io.pmpResp <> pmp_check.head.resp 1921*c590fb32Scz4e vSegmentUnit.io.flush_sbuffer.empty := stIsEmpty 1922*c590fb32Scz4e vSegmentUnit.io.redirect <> redirect 1923*c590fb32Scz4e vSegmentUnit.io.rdcache.resp.bits := dcache.io.lsu.load(0).resp.bits 1924*c590fb32Scz4e vSegmentUnit.io.rdcache.resp.valid := dcache.io.lsu.load(0).resp.valid 1925*c590fb32Scz4e vSegmentUnit.io.rdcache.s2_bank_conflict := dcache.io.lsu.load(0).s2_bank_conflict 1926*c590fb32Scz4e // ------------------------- 1927*c590fb32Scz4e // Vector Segment Triggers 1928*c590fb32Scz4e // ------------------------- 1929*c590fb32Scz4e vSegmentUnit.io.fromCsrTrigger.tdataVec := tdata 1930*c590fb32Scz4e vSegmentUnit.io.fromCsrTrigger.tEnableVec := tEnable 1931*c590fb32Scz4e vSegmentUnit.io.fromCsrTrigger.triggerCanRaiseBpExp := triggerCanRaiseBpExp 1932*c590fb32Scz4e vSegmentUnit.io.fromCsrTrigger.debugMode := debugMode 1933*c590fb32Scz4e 1934*c590fb32Scz4e // reset tree of MemBlock 1935*c590fb32Scz4e if (p(DebugOptionsKey).ResetGen) { 1936*c590fb32Scz4e val leftResetTree = ResetGenNode( 1937*c590fb32Scz4e Seq( 1938*c590fb32Scz4e ModuleNode(ptw), 1939*c590fb32Scz4e ModuleNode(ptw_to_l2_buffer), 1940*c590fb32Scz4e ModuleNode(lsq), 1941*c590fb32Scz4e ModuleNode(dtlb_st_tlb_st), 1942*c590fb32Scz4e ModuleNode(dtlb_prefetch_tlb_prefetch), 1943*c590fb32Scz4e ModuleNode(pmp) 1944*c590fb32Scz4e ) 1945*c590fb32Scz4e ++ pmp_checkers.map(ModuleNode(_)) 1946*c590fb32Scz4e ++ (if (prefetcherOpt.isDefined) Seq(ModuleNode(prefetcherOpt.get)) else Nil) 1947*c590fb32Scz4e ++ (if (l1PrefetcherOpt.isDefined) Seq(ModuleNode(l1PrefetcherOpt.get)) else Nil) 1948*c590fb32Scz4e ) 1949*c590fb32Scz4e val rightResetTree = ResetGenNode( 1950*c590fb32Scz4e Seq( 1951*c590fb32Scz4e ModuleNode(sbuffer), 1952*c590fb32Scz4e ModuleNode(dtlb_ld_tlb_ld), 1953*c590fb32Scz4e ModuleNode(dcache), 1954*c590fb32Scz4e ModuleNode(l1d_to_l2_buffer), 1955*c590fb32Scz4e CellNode(io.reset_backend) 1956*c590fb32Scz4e ) 1957*c590fb32Scz4e ) 1958*c590fb32Scz4e ResetGen(leftResetTree, reset, sim = false) 1959*c590fb32Scz4e ResetGen(rightResetTree, reset, sim = false) 1960*c590fb32Scz4e } else { 1961*c590fb32Scz4e io.reset_backend := DontCare 1962*c590fb32Scz4e } 1963*c590fb32Scz4e io.resetInFrontendBypass.toL2Top := io.resetInFrontendBypass.fromFrontend 1964*c590fb32Scz4e // trace interface 1965*c590fb32Scz4e val traceToL2Top = io.traceCoreInterfaceBypass.toL2Top 1966*c590fb32Scz4e val traceFromBackend = io.traceCoreInterfaceBypass.fromBackend 1967*c590fb32Scz4e traceFromBackend.fromEncoder := RegNext(traceToL2Top.fromEncoder) 1968*c590fb32Scz4e traceToL2Top.toEncoder.trap := RegEnable( 1969*c590fb32Scz4e traceFromBackend.toEncoder.trap, 1970*c590fb32Scz4e traceFromBackend.toEncoder.groups(0).valid && Itype.isTrap(traceFromBackend.toEncoder.groups(0).bits.itype) 1971*c590fb32Scz4e ) 1972*c590fb32Scz4e traceToL2Top.toEncoder.priv := RegEnable( 1973*c590fb32Scz4e traceFromBackend.toEncoder.priv, 1974*c590fb32Scz4e traceFromBackend.toEncoder.groups(0).valid 1975*c590fb32Scz4e ) 1976*c590fb32Scz4e (0 until TraceGroupNum).foreach { i => 1977*c590fb32Scz4e traceToL2Top.toEncoder.groups(i).valid := RegNext(traceFromBackend.toEncoder.groups(i).valid) 1978*c590fb32Scz4e traceToL2Top.toEncoder.groups(i).bits.iretire := RegNext(traceFromBackend.toEncoder.groups(i).bits.iretire) 1979*c590fb32Scz4e traceToL2Top.toEncoder.groups(i).bits.itype := RegNext(traceFromBackend.toEncoder.groups(i).bits.itype) 1980*c590fb32Scz4e traceToL2Top.toEncoder.groups(i).bits.ilastsize := RegEnable( 1981*c590fb32Scz4e traceFromBackend.toEncoder.groups(i).bits.ilastsize, 1982*c590fb32Scz4e traceFromBackend.toEncoder.groups(i).valid 1983*c590fb32Scz4e ) 1984*c590fb32Scz4e traceToL2Top.toEncoder.groups(i).bits.iaddr := RegEnable( 1985*c590fb32Scz4e traceFromBackend.toEncoder.groups(i).bits.iaddr, 1986*c590fb32Scz4e traceFromBackend.toEncoder.groups(i).valid 1987*c590fb32Scz4e ) + (RegEnable( 1988*c590fb32Scz4e traceFromBackend.toEncoder.groups(i).bits.ftqOffset.getOrElse(0.U), 1989*c590fb32Scz4e traceFromBackend.toEncoder.groups(i).valid 1990*c590fb32Scz4e ) << instOffsetBits) 1991*c590fb32Scz4e } 1992*c590fb32Scz4e 1993*c590fb32Scz4e 1994*c590fb32Scz4e io.mem_to_ooo.storeDebugInfo := DontCare 1995*c590fb32Scz4e // store event difftest information 1996*c590fb32Scz4e if (env.EnableDifftest) { 1997*c590fb32Scz4e (0 until EnsbufferWidth).foreach{i => 1998*c590fb32Scz4e io.mem_to_ooo.storeDebugInfo(i).robidx := sbuffer.io.vecDifftestInfo(i).bits.robIdx 1999*c590fb32Scz4e sbuffer.io.vecDifftestInfo(i).bits.pc := io.mem_to_ooo.storeDebugInfo(i).pc 2000*c590fb32Scz4e } 2001*c590fb32Scz4e } 2002*c590fb32Scz4e 2003*c590fb32Scz4e // top-down info 2004*c590fb32Scz4e dcache.io.debugTopDown.robHeadVaddr := io.debugTopDown.robHeadVaddr 2005*c590fb32Scz4e dtlbRepeater.io.debugTopDown.robHeadVaddr := io.debugTopDown.robHeadVaddr 2006*c590fb32Scz4e lsq.io.debugTopDown.robHeadVaddr := io.debugTopDown.robHeadVaddr 2007*c590fb32Scz4e io.debugTopDown.toCore.robHeadMissInDCache := dcache.io.debugTopDown.robHeadMissInDCache 2008*c590fb32Scz4e io.debugTopDown.toCore.robHeadTlbReplay := lsq.io.debugTopDown.robHeadTlbReplay 2009*c590fb32Scz4e io.debugTopDown.toCore.robHeadTlbMiss := lsq.io.debugTopDown.robHeadTlbMiss 2010*c590fb32Scz4e io.debugTopDown.toCore.robHeadLoadVio := lsq.io.debugTopDown.robHeadLoadVio 2011*c590fb32Scz4e io.debugTopDown.toCore.robHeadLoadMSHR := lsq.io.debugTopDown.robHeadLoadMSHR 2012*c590fb32Scz4e dcache.io.debugTopDown.robHeadOtherReplay := lsq.io.debugTopDown.robHeadOtherReplay 2013*c590fb32Scz4e dcache.io.debugRolling := io.debugRolling 2014*c590fb32Scz4e 2015*c590fb32Scz4e lsq.io.noUopsIssued := io.topDownInfo.toBackend.noUopsIssued 2016*c590fb32Scz4e io.topDownInfo.toBackend.lqEmpty := lsq.io.lqEmpty 2017*c590fb32Scz4e io.topDownInfo.toBackend.sqEmpty := lsq.io.sqEmpty 2018*c590fb32Scz4e io.topDownInfo.toBackend.l1Miss := dcache.io.l1Miss 2019*c590fb32Scz4e io.topDownInfo.toBackend.l2TopMiss.l2Miss := RegNext(io.topDownInfo.fromL2Top.l2Miss) 2020*c590fb32Scz4e io.topDownInfo.toBackend.l2TopMiss.l3Miss := RegNext(io.topDownInfo.fromL2Top.l3Miss) 2021*c590fb32Scz4e 2022*c590fb32Scz4e val hyLdDeqCount = PopCount(io.ooo_to_mem.issueHya.map(x => x.valid && FuType.isLoad(x.bits.uop.fuType))) 2023*c590fb32Scz4e val hyStDeqCount = PopCount(io.ooo_to_mem.issueHya.map(x => x.valid && FuType.isStore(x.bits.uop.fuType))) 2024*c590fb32Scz4e val ldDeqCount = PopCount(io.ooo_to_mem.issueLda.map(_.valid)) +& hyLdDeqCount 2025*c590fb32Scz4e val stDeqCount = PopCount(io.ooo_to_mem.issueSta.take(StaCnt).map(_.valid)) +& hyStDeqCount 2026*c590fb32Scz4e val iqDeqCount = ldDeqCount +& stDeqCount 2027*c590fb32Scz4e XSPerfAccumulate("load_iq_deq_count", ldDeqCount) 2028*c590fb32Scz4e XSPerfHistogram("load_iq_deq_count", ldDeqCount, true.B, 0, LdExuCnt + 1) 2029*c590fb32Scz4e XSPerfAccumulate("store_iq_deq_count", stDeqCount) 2030*c590fb32Scz4e XSPerfHistogram("store_iq_deq_count", stDeqCount, true.B, 0, StAddrCnt + 1) 2031*c590fb32Scz4e XSPerfAccumulate("ls_iq_deq_count", iqDeqCount) 2032*c590fb32Scz4e 2033*c590fb32Scz4e val pfevent = Module(new PFEvent) 2034*c590fb32Scz4e pfevent.io.distribute_csr := csrCtrl.distribute_csr 2035*c590fb32Scz4e val csrevents = pfevent.io.hpmevent.slice(16,24) 2036*c590fb32Scz4e 2037*c590fb32Scz4e val perfFromUnits = (loadUnits ++ Seq(sbuffer, lsq, dcache)).flatMap(_.getPerfEvents) 2038*c590fb32Scz4e val perfFromPTW = perfEventsPTW.map(x => ("PTW_" + x._1, x._2)) 2039*c590fb32Scz4e val perfBlock = Seq(("ldDeqCount", ldDeqCount), 2040*c590fb32Scz4e ("stDeqCount", stDeqCount)) 2041*c590fb32Scz4e // let index = 0 be no event 2042*c590fb32Scz4e val allPerfEvents = Seq(("noEvent", 0.U)) ++ perfFromUnits ++ perfFromPTW ++ perfBlock 2043*c590fb32Scz4e 2044*c590fb32Scz4e if (printEventCoding) { 2045*c590fb32Scz4e for (((name, inc), i) <- allPerfEvents.zipWithIndex) { 2046*c590fb32Scz4e println("MemBlock perfEvents Set", name, inc, i) 2047*c590fb32Scz4e } 2048*c590fb32Scz4e } 2049*c590fb32Scz4e 2050*c590fb32Scz4e val allPerfInc = allPerfEvents.map(_._2.asTypeOf(new PerfEvent)) 2051*c590fb32Scz4e val perfEvents = HPerfMonitor(csrevents, allPerfInc).getPerfEvents 2052*c590fb32Scz4e generatePerfEvent() 2053*c590fb32Scz4e} 2054*c590fb32Scz4e 2055*c590fb32Scz4eclass MemBlock()(implicit p: Parameters) extends LazyModule 2056*c590fb32Scz4e with HasXSParameter { 2057*c590fb32Scz4e override def shouldBeInlined: Boolean = false 2058*c590fb32Scz4e 2059*c590fb32Scz4e val inner = LazyModule(new MemBlockInlined()) 2060*c590fb32Scz4e 2061*c590fb32Scz4e lazy val module = new MemBlockImp(this) 2062*c590fb32Scz4e} 2063*c590fb32Scz4e 2064*c590fb32Scz4eclass MemBlockImp(wrapper: MemBlock) extends LazyModuleImp(wrapper) { 2065*c590fb32Scz4e val io = IO(wrapper.inner.module.io.cloneType) 2066*c590fb32Scz4e val io_perf = IO(wrapper.inner.module.io_perf.cloneType) 2067*c590fb32Scz4e io <> wrapper.inner.module.io 2068*c590fb32Scz4e io_perf <> wrapper.inner.module.io_perf 2069*c590fb32Scz4e 2070*c590fb32Scz4e if (p(DebugOptionsKey).ResetGen) { 2071*c590fb32Scz4e ResetGen(ResetGenNode(Seq(ModuleNode(wrapper.inner.module))), reset, sim = false) 2072*c590fb32Scz4e } 2073*c590fb32Scz4e} 2074