xref: /XiangShan/src/main/scala/xiangshan/mem/MemBlock.scala (revision c590fb326b3540db0e5d81d49ff03b6158012466)
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