xref: /XiangShan/src/main/scala/xiangshan/L2Top.scala (revision aee6a6d1b294409cf4c5599677544021afb6e7b3)
14e12f40bSzhanglinjuan/***************************************************************************************
24e12f40bSzhanglinjuan  * Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences
34e12f40bSzhanglinjuan  * Copyright (c) 2020-2021 Peng Cheng Laboratory
44e12f40bSzhanglinjuan  *
54e12f40bSzhanglinjuan  * XiangShan is licensed under Mulan PSL v2.
64e12f40bSzhanglinjuan  * You can use this software according to the terms and conditions of the Mulan PSL v2.
74e12f40bSzhanglinjuan  * You may obtain a copy of Mulan PSL v2 at:
84e12f40bSzhanglinjuan  *          http://license.coscl.org.cn/MulanPSL2
94e12f40bSzhanglinjuan  *
104e12f40bSzhanglinjuan  * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
114e12f40bSzhanglinjuan  * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
124e12f40bSzhanglinjuan  * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
134e12f40bSzhanglinjuan  *
144e12f40bSzhanglinjuan  * See the Mulan PSL v2 for more details.
154e12f40bSzhanglinjuan  ***************************************************************************************/
164e12f40bSzhanglinjuan
174e12f40bSzhanglinjuanpackage xiangshan
184e12f40bSzhanglinjuan
194e12f40bSzhanglinjuanimport chisel3._
204e12f40bSzhanglinjuanimport org.chipsalliance.cde.config._
214e12f40bSzhanglinjuanimport chisel3.util.{Valid, ValidIO}
224e12f40bSzhanglinjuanimport freechips.rocketchip.diplomacy._
234e12f40bSzhanglinjuanimport freechips.rocketchip.interrupts._
244e12f40bSzhanglinjuanimport freechips.rocketchip.tile.{BusErrorUnit, BusErrorUnitParams, BusErrors}
254e12f40bSzhanglinjuanimport freechips.rocketchip.tilelink._
26*aee6a6d1SYanqin Liimport coupledL2.{CoupledL2, L2ParamKey}
274e12f40bSzhanglinjuanimport system.HasSoCParameter
284e12f40bSzhanglinjuanimport top.BusPerfMonitor
294e12f40bSzhanglinjuanimport utility.{DelayN, ResetGen, TLClientsMerger, TLEdgeBuffer, TLLogger}
30*aee6a6d1SYanqin Liimport xiangshan.cache.mmu.TlbRequestIO
314e12f40bSzhanglinjuan
324e12f40bSzhanglinjuanclass L1BusErrorUnitInfo(implicit val p: Parameters) extends Bundle with HasSoCParameter {
334e12f40bSzhanglinjuan  val ecc_error = Valid(UInt(soc.PAddrBits.W))
344e12f40bSzhanglinjuan}
354e12f40bSzhanglinjuan
364e12f40bSzhanglinjuanclass XSL1BusErrors()(implicit val p: Parameters) extends BusErrors {
374e12f40bSzhanglinjuan  val icache = new L1BusErrorUnitInfo
384e12f40bSzhanglinjuan  val dcache = new L1BusErrorUnitInfo
394e12f40bSzhanglinjuan  val l2 = new L1BusErrorUnitInfo
404e12f40bSzhanglinjuan
414e12f40bSzhanglinjuan  override def toErrorList: List[Option[(ValidIO[UInt], String, String)]] =
424e12f40bSzhanglinjuan    List(
434e12f40bSzhanglinjuan      Some(icache.ecc_error, "I_ECC", "Icache ecc error"),
444e12f40bSzhanglinjuan      Some(dcache.ecc_error, "D_ECC", "Dcache ecc error"),
454e12f40bSzhanglinjuan      Some(l2.ecc_error, "L2_ECC", "L2Cache ecc error")
464e12f40bSzhanglinjuan    )
474e12f40bSzhanglinjuan}
484e12f40bSzhanglinjuan
494e12f40bSzhanglinjuan/**
504e12f40bSzhanglinjuan  *   L2Top contains everything between Core and XSTile-IO
514e12f40bSzhanglinjuan  */
524e12f40bSzhanglinjuanclass L2Top()(implicit p: Parameters) extends LazyModule
534e12f40bSzhanglinjuan  with HasXSParameter
544e12f40bSzhanglinjuan  with HasSoCParameter
554e12f40bSzhanglinjuan{
564e12f40bSzhanglinjuan  def chainBuffer(depth: Int, n: String): (Seq[LazyModule], TLNode) = {
574e12f40bSzhanglinjuan    val buffers = Seq.fill(depth){ LazyModule(new TLBuffer()) }
584e12f40bSzhanglinjuan    buffers.zipWithIndex.foreach{ case (b, i) => {
594e12f40bSzhanglinjuan      b.suggestName(s"${n}_${i}")
604e12f40bSzhanglinjuan    }}
614e12f40bSzhanglinjuan    val node = buffers.map(_.node.asInstanceOf[TLNode]).reduce(_ :*=* _)
624e12f40bSzhanglinjuan    (buffers, node)
634e12f40bSzhanglinjuan  }
644e12f40bSzhanglinjuan  // =========== Components ============
654e12f40bSzhanglinjuan  val l1_xbar = TLXbar()
664e12f40bSzhanglinjuan  val mmio_xbar = TLXbar()
674e12f40bSzhanglinjuan  val mmio_port = TLIdentityNode() // to L3
684e12f40bSzhanglinjuan  val memory_port = TLIdentityNode()
694e12f40bSzhanglinjuan  val beu = LazyModule(new BusErrorUnit(
704e12f40bSzhanglinjuan    new XSL1BusErrors(), BusErrorUnitParams(0x38010000)
714e12f40bSzhanglinjuan  ))
724e12f40bSzhanglinjuan
734e12f40bSzhanglinjuan  val i_mmio_port = TLTempNode()
744e12f40bSzhanglinjuan  val d_mmio_port = TLTempNode()
754e12f40bSzhanglinjuan
764e12f40bSzhanglinjuan  val misc_l2_pmu = BusPerfMonitor(name = "Misc_L2", enable = !debugOpts.FPGAPlatform) // l1D & l1I & PTW
774e12f40bSzhanglinjuan  val l2_l3_pmu = BusPerfMonitor(name = "L2_L3", enable = !debugOpts.FPGAPlatform, stat_latency = true)
78c20095f4SChen Xi  val xbar_l2_buffer = TLBuffer()
794e12f40bSzhanglinjuan
804e12f40bSzhanglinjuan  val enbale_tllog = !debugOpts.FPGAPlatform && debugOpts.AlwaysBasicDB
814e12f40bSzhanglinjuan  val l1d_logger = TLLogger(s"L2_L1D_${coreParams.HartId}", enbale_tllog)
824e12f40bSzhanglinjuan  val l1i_logger = TLLogger(s"L2_L1I_${coreParams.HartId}", enbale_tllog)
834e12f40bSzhanglinjuan  val ptw_logger = TLLogger(s"L2_PTW_${coreParams.HartId}", enbale_tllog)
84c20095f4SChen Xi  val ptw_to_l2_buffer = LazyModule(new TLBuffer)
85c20095f4SChen Xi  val i_mmio_buffer = LazyModule(new TLBuffer)
864e12f40bSzhanglinjuan
874e12f40bSzhanglinjuan  val clint_int_node = IntIdentityNode()
884e12f40bSzhanglinjuan  val debug_int_node = IntIdentityNode()
894e12f40bSzhanglinjuan  val plic_int_node = IntIdentityNode()
904e12f40bSzhanglinjuan
914e12f40bSzhanglinjuan  val l2cache = coreParams.L2CacheParamsOpt.map(l2param =>
924e12f40bSzhanglinjuan    LazyModule(new CoupledL2()(new Config((_, _, _) => {
934e12f40bSzhanglinjuan      case L2ParamKey => l2param.copy(
944e12f40bSzhanglinjuan          hartIds = Seq(p(XSCoreParamsKey).HartId),
954e12f40bSzhanglinjuan          FPGAPlatform = debugOpts.FPGAPlatform
964e12f40bSzhanglinjuan        )
974e12f40bSzhanglinjuan    })))
984e12f40bSzhanglinjuan  )
994e12f40bSzhanglinjuan  val l2_binder = coreParams.L2CacheParamsOpt.map(_ => BankBinder(coreParams.L2NBanks, 64))
1004e12f40bSzhanglinjuan
1014e12f40bSzhanglinjuan  // =========== Connection ============
1024e12f40bSzhanglinjuan  // l2 to l2_binder, then to memory_port
1034e12f40bSzhanglinjuan  l2_binder match {
1044e12f40bSzhanglinjuan    case Some(binder) =>
1054e12f40bSzhanglinjuan      memory_port := l2_l3_pmu := TLClientsMerger() := TLXbar() :=* binder :*= l2cache.get.node
1064e12f40bSzhanglinjuan    case None =>
1074e12f40bSzhanglinjuan      memory_port := l1_xbar
1084e12f40bSzhanglinjuan  }
1094e12f40bSzhanglinjuan
1104e12f40bSzhanglinjuan  mmio_xbar := TLBuffer.chainNode(2) := i_mmio_port
1114e12f40bSzhanglinjuan  mmio_xbar := TLBuffer.chainNode(2) := d_mmio_port
1124e12f40bSzhanglinjuan  beu.node := TLBuffer.chainNode(1) := mmio_xbar
1134e12f40bSzhanglinjuan  mmio_port := TLBuffer() := mmio_xbar
1144e12f40bSzhanglinjuan
1154e12f40bSzhanglinjuan  class L2TopImp(wrapper: LazyModule) extends LazyModuleImp(wrapper) {
1164e12f40bSzhanglinjuan    val beu_errors = IO(Input(chiselTypeOf(beu.module.io.errors)))
1174e12f40bSzhanglinjuan    val reset_vector = IO(new Bundle {
1184e12f40bSzhanglinjuan      val fromTile = Input(UInt(PAddrBits.W))
1194e12f40bSzhanglinjuan      val toCore = Output(UInt(PAddrBits.W))
1204e12f40bSzhanglinjuan    })
1214e12f40bSzhanglinjuan    val hartId = IO(new Bundle() {
1224e12f40bSzhanglinjuan      val fromTile = Input(UInt(64.W))
1234e12f40bSzhanglinjuan      val toCore = Output(UInt(64.W))
1244e12f40bSzhanglinjuan    })
1254e12f40bSzhanglinjuan    val cpu_halt = IO(new Bundle() {
1264e12f40bSzhanglinjuan      val fromCore = Input(Bool())
1274e12f40bSzhanglinjuan      val toTile = Output(Bool())
1284e12f40bSzhanglinjuan    })
1294e12f40bSzhanglinjuan    val debugTopDown = IO(new Bundle() {
130*aee6a6d1SYanqin Li      val robTrueCommit = Input(UInt(64.W))
1314e12f40bSzhanglinjuan      val robHeadPaddr = Flipped(Valid(UInt(36.W)))
1324e12f40bSzhanglinjuan      val l2MissMatch = Output(Bool())
1334e12f40bSzhanglinjuan    })
134*aee6a6d1SYanqin Li    val l2_tlb_req = IO(new TlbRequestIO(nRespDups = 2))
1354e12f40bSzhanglinjuan
1364e12f40bSzhanglinjuan    val resetDelayN = Module(new DelayN(UInt(PAddrBits.W), 5))
1374e12f40bSzhanglinjuan
1384e12f40bSzhanglinjuan    beu.module.io.errors <> beu_errors
1394e12f40bSzhanglinjuan    resetDelayN.io.in := reset_vector.fromTile
1404e12f40bSzhanglinjuan    reset_vector.toCore := resetDelayN.io.out
1414e12f40bSzhanglinjuan    hartId.toCore := hartId.fromTile
1424e12f40bSzhanglinjuan    cpu_halt.toTile := cpu_halt.fromCore
1434e12f40bSzhanglinjuan    dontTouch(hartId)
1444e12f40bSzhanglinjuan    dontTouch(cpu_halt)
1454e12f40bSzhanglinjuan
146d2945707SHuijin Li    val l2_hint = IO(ValidIO(new L2ToL1Hint())) // TODO: parameterize this
1474e12f40bSzhanglinjuan    if (l2cache.isDefined) {
1484e12f40bSzhanglinjuan      l2_hint := l2cache.get.module.io.l2_hint
1494e12f40bSzhanglinjuan      // debugTopDown <> l2cache.get.module.io.debugTopDown
1504e12f40bSzhanglinjuan      l2cache.get.module.io.debugTopDown.robHeadPaddr := DontCare
151f57f7f2aSYangyu Chen      l2cache.get.module.io.hartId := hartId.fromTile
1524e12f40bSzhanglinjuan      l2cache.get.module.io.debugTopDown.robHeadPaddr.head := debugTopDown.robHeadPaddr
153*aee6a6d1SYanqin Li      l2cache.get.module.io.debugTopDown.robTrueCommit := debugTopDown.robTrueCommit
1544e12f40bSzhanglinjuan      debugTopDown.l2MissMatch := l2cache.get.module.io.debugTopDown.l2MissMatch.head
155*aee6a6d1SYanqin Li
156*aee6a6d1SYanqin Li      /* l2 tlb */
157*aee6a6d1SYanqin Li      l2_tlb_req.req.bits := DontCare
158*aee6a6d1SYanqin Li      l2_tlb_req.req.valid := l2cache.get.module.io.l2_tlb_req.req.valid
159*aee6a6d1SYanqin Li      l2_tlb_req.resp.ready := l2cache.get.module.io.l2_tlb_req.resp.ready
160*aee6a6d1SYanqin Li      l2_tlb_req.req.bits.vaddr := l2cache.get.module.io.l2_tlb_req.req.bits.vaddr
161*aee6a6d1SYanqin Li      l2_tlb_req.req.bits.cmd := l2cache.get.module.io.l2_tlb_req.req.bits.cmd
162*aee6a6d1SYanqin Li      l2_tlb_req.req.bits.size := l2cache.get.module.io.l2_tlb_req.req.bits.size
163*aee6a6d1SYanqin Li      l2_tlb_req.req.bits.kill := l2cache.get.module.io.l2_tlb_req.req.bits.kill
164*aee6a6d1SYanqin Li      l2_tlb_req.req.bits.no_translate := l2cache.get.module.io.l2_tlb_req.req.bits.no_translate
165*aee6a6d1SYanqin Li      l2_tlb_req.req_kill := l2cache.get.module.io.l2_tlb_req.req_kill
166*aee6a6d1SYanqin Li      l2cache.get.module.io.l2_tlb_req.resp.valid := l2_tlb_req.resp.valid
167*aee6a6d1SYanqin Li      l2cache.get.module.io.l2_tlb_req.req.ready := l2_tlb_req.req.ready
168*aee6a6d1SYanqin Li      l2cache.get.module.io.l2_tlb_req.resp.bits.paddr.head := l2_tlb_req.resp.bits.paddr.head
169*aee6a6d1SYanqin Li      l2cache.get.module.io.l2_tlb_req.resp.bits.miss := l2_tlb_req.resp.bits.miss
170*aee6a6d1SYanqin Li      l2cache.get.module.io.l2_tlb_req.resp.bits.excp.head <> l2_tlb_req.resp.bits.excp.head
1714e12f40bSzhanglinjuan    } else {
1724e12f40bSzhanglinjuan      l2_hint := 0.U.asTypeOf(l2_hint)
1734e12f40bSzhanglinjuan      debugTopDown <> DontCare
174*aee6a6d1SYanqin Li
175*aee6a6d1SYanqin Li      l2_tlb_req.req.valid := false.B
176*aee6a6d1SYanqin Li      l2_tlb_req.req.bits := DontCare
177*aee6a6d1SYanqin Li      l2_tlb_req.req_kill := DontCare
178*aee6a6d1SYanqin Li      l2_tlb_req.resp.ready := true.B
179*aee6a6d1SYanqin Li      l2cache.get.module.io.l2_tlb_req.req.ready := true.B
180*aee6a6d1SYanqin Li      l2cache.get.module.io.l2_tlb_req.resp.valid := false.B
181*aee6a6d1SYanqin Li      l2cache.get.module.io.l2_tlb_req.resp.bits := DontCare
1824e12f40bSzhanglinjuan    }
1834e12f40bSzhanglinjuan  }
1844e12f40bSzhanglinjuan
1854e12f40bSzhanglinjuan  lazy val module = new L2TopImp(this)
1864e12f40bSzhanglinjuan}