xref: /XiangShan/src/main/scala/xiangshan/L2Top.scala (revision 45f43e6e5f88874a7573ff096d1e5c2855bd16c7)
1/***************************************************************************************
2  * Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences
3  * Copyright (c) 2020-2021 Peng Cheng Laboratory
4  *
5  * XiangShan is licensed under Mulan PSL v2.
6  * You can use this software according to the terms and conditions of the Mulan PSL v2.
7  * You may obtain a copy of Mulan PSL v2 at:
8  *          http://license.coscl.org.cn/MulanPSL2
9  *
10  * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
11  * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
12  * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
13  *
14  * See the Mulan PSL v2 for more details.
15  ***************************************************************************************/
16
17package xiangshan
18
19import chisel3._
20import org.chipsalliance.cde.config._
21import chisel3.util.{Valid, ValidIO}
22import freechips.rocketchip.diplomacy._
23import freechips.rocketchip.interrupts._
24import freechips.rocketchip.tile.{BusErrorUnit, BusErrorUnitParams, BusErrors}
25import freechips.rocketchip.tilelink._
26import coupledL2.{L2ParamKey, CoupledL2}
27import system.HasSoCParameter
28import top.BusPerfMonitor
29import utility.{DelayN, ResetGen, TLClientsMerger, TLEdgeBuffer, TLLogger}
30
31class L1BusErrorUnitInfo(implicit val p: Parameters) extends Bundle with HasSoCParameter {
32  val ecc_error = Valid(UInt(soc.PAddrBits.W))
33}
34
35class XSL1BusErrors()(implicit val p: Parameters) extends BusErrors {
36  val icache = new L1BusErrorUnitInfo
37  val dcache = new L1BusErrorUnitInfo
38  val l2 = new L1BusErrorUnitInfo
39
40  override def toErrorList: List[Option[(ValidIO[UInt], String, String)]] =
41    List(
42      Some(icache.ecc_error, "I_ECC", "Icache ecc error"),
43      Some(dcache.ecc_error, "D_ECC", "Dcache ecc error"),
44      Some(l2.ecc_error, "L2_ECC", "L2Cache ecc error")
45    )
46}
47
48/**
49  *   L2Top contains everything between Core and XSTile-IO
50  */
51class L2Top()(implicit p: Parameters) extends LazyModule
52  with HasXSParameter
53  with HasSoCParameter
54{
55  def chainBuffer(depth: Int, n: String): (Seq[LazyModule], TLNode) = {
56    val buffers = Seq.fill(depth){ LazyModule(new TLBuffer()) }
57    buffers.zipWithIndex.foreach{ case (b, i) => {
58      b.suggestName(s"${n}_${i}")
59    }}
60    val node = buffers.map(_.node.asInstanceOf[TLNode]).reduce(_ :*=* _)
61    (buffers, node)
62  }
63  // =========== Components ============
64  val l1_xbar = TLXbar()
65  val mmio_xbar = TLXbar()
66  val mmio_port = TLIdentityNode() // to L3
67  val memory_port = TLIdentityNode()
68  val beu = LazyModule(new BusErrorUnit(
69    new XSL1BusErrors(), BusErrorUnitParams(0x38010000)
70  ))
71
72  val i_mmio_port = TLTempNode()
73  val d_mmio_port = TLTempNode()
74
75  val misc_l2_pmu = BusPerfMonitor(name = "Misc_L2", enable = !debugOpts.FPGAPlatform) // l1D & l1I & PTW
76  val l2_l3_pmu = BusPerfMonitor(name = "L2_L3", enable = !debugOpts.FPGAPlatform, stat_latency = true)
77  val xbar_l2_buffer = TLBuffer()
78
79  val enbale_tllog = !debugOpts.FPGAPlatform && debugOpts.AlwaysBasicDB
80  val l1d_logger = TLLogger(s"L2_L1D_${coreParams.HartId}", enbale_tllog)
81  val l1i_logger = TLLogger(s"L2_L1I_${coreParams.HartId}", enbale_tllog)
82  val ptw_logger = TLLogger(s"L2_PTW_${coreParams.HartId}", enbale_tllog)
83  val ptw_to_l2_buffer = LazyModule(new TLBuffer)
84  val i_mmio_buffer = LazyModule(new TLBuffer)
85
86  val clint_int_node = IntIdentityNode()
87  val debug_int_node = IntIdentityNode()
88  val plic_int_node = IntIdentityNode()
89
90  val l2cache = coreParams.L2CacheParamsOpt.map(l2param =>
91    LazyModule(new CoupledL2()(new Config((_, _, _) => {
92      case L2ParamKey => l2param.copy(
93          hartIds = Seq(p(XSCoreParamsKey).HartId),
94          FPGAPlatform = debugOpts.FPGAPlatform
95        )
96    })))
97  )
98  val l2_binder = coreParams.L2CacheParamsOpt.map(_ => BankBinder(coreParams.L2NBanks, 64))
99
100  // =========== Connection ============
101  // l2 to l2_binder, then to memory_port
102  l2_binder match {
103    case Some(binder) =>
104      memory_port := l2_l3_pmu := TLClientsMerger() := TLXbar() :=* binder :*= l2cache.get.node
105    case None =>
106      memory_port := l1_xbar
107  }
108
109  mmio_xbar := TLBuffer.chainNode(2) := i_mmio_port
110  mmio_xbar := TLBuffer.chainNode(2) := d_mmio_port
111  beu.node := TLBuffer.chainNode(1) := mmio_xbar
112  mmio_port := TLBuffer() := mmio_xbar
113
114  class L2TopImp(wrapper: LazyModule) extends LazyModuleImp(wrapper) {
115    val beu_errors = IO(Input(chiselTypeOf(beu.module.io.errors)))
116    val reset_vector = IO(new Bundle {
117      val fromTile = Input(UInt(PAddrBits.W))
118      val toCore = Output(UInt(PAddrBits.W))
119    })
120    val hartId = IO(new Bundle() {
121      val fromTile = Input(UInt(64.W))
122      val toCore = Output(UInt(64.W))
123    })
124    val cpu_halt = IO(new Bundle() {
125      val fromCore = Input(Bool())
126      val toTile = Output(Bool())
127    })
128    val debugTopDown = IO(new Bundle() {
129      val robHeadPaddr = Flipped(Valid(UInt(36.W)))
130      val l2MissMatch = Output(Bool())
131    })
132
133    val resetDelayN = Module(new DelayN(UInt(PAddrBits.W), 5))
134
135    beu.module.io.errors <> beu_errors
136    resetDelayN.io.in := reset_vector.fromTile
137    reset_vector.toCore := resetDelayN.io.out
138    hartId.toCore := hartId.fromTile
139    cpu_halt.toTile := cpu_halt.fromCore
140    dontTouch(hartId)
141    dontTouch(cpu_halt)
142
143    val l2_hint = IO(ValidIO(new L2ToL1Hint())) // TODO: parameterize this
144    if (l2cache.isDefined) {
145      l2_hint := l2cache.get.module.io.l2_hint
146      // debugTopDown <> l2cache.get.module.io.debugTopDown
147      l2cache.get.module.io.debugTopDown.robHeadPaddr := DontCare
148      l2cache.get.module.io.debugTopDown.robHeadPaddr.head := debugTopDown.robHeadPaddr
149      debugTopDown.l2MissMatch := l2cache.get.module.io.debugTopDown.l2MissMatch.head
150    } else {
151      l2_hint := 0.U.asTypeOf(l2_hint)
152      debugTopDown <> DontCare
153    }
154  }
155
156  lazy val module = new L2TopImp(this)
157}