xref: /XiangShan/src/main/scala/xiangshan/L2Top.scala (revision 4daa5bf3c3f27e7fd090866d52405b21e107eb8d)
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, MaxHartIdBits}
25import freechips.rocketchip.tilelink._
26import coupledL2.{CoupledL2, L2ParamKey}
27import system.HasSoCParameter
28import top.BusPerfMonitor
29import utility.{DelayN, ResetGen, TLClientsMerger, TLEdgeBuffer, TLLogger}
30import xiangshan.cache.mmu.TlbRequestIO
31
32class L1BusErrorUnitInfo(implicit val p: Parameters) extends Bundle with HasSoCParameter {
33  val ecc_error = Valid(UInt(soc.PAddrBits.W))
34}
35
36class XSL1BusErrors()(implicit val p: Parameters) extends BusErrors {
37  val icache = new L1BusErrorUnitInfo
38  val dcache = new L1BusErrorUnitInfo
39  val l2 = new L1BusErrorUnitInfo
40
41  override def toErrorList: List[Option[(ValidIO[UInt], String, String)]] =
42    List(
43      Some(icache.ecc_error, "I_ECC", "Icache ecc error"),
44      Some(dcache.ecc_error, "D_ECC", "Dcache ecc error"),
45      Some(l2.ecc_error, "L2_ECC", "L2Cache ecc error")
46    )
47}
48
49/**
50  *   L2Top contains everything between Core and XSTile-IO
51  */
52class L2Top()(implicit p: Parameters) extends LazyModule
53  with HasXSParameter
54  with HasSoCParameter
55{
56  def chainBuffer(depth: Int, n: String): (Seq[LazyModule], TLNode) = {
57    val buffers = Seq.fill(depth){ LazyModule(new TLBuffer()) }
58    buffers.zipWithIndex.foreach{ case (b, i) => {
59      b.suggestName(s"${n}_${i}")
60    }}
61    val node = buffers.map(_.node.asInstanceOf[TLNode]).reduce(_ :*=* _)
62    (buffers, node)
63  }
64  // =========== Components ============
65  val l1_xbar = TLXbar()
66  val mmio_xbar = TLXbar()
67  val mmio_port = TLIdentityNode() // to L3
68  val memory_port = TLIdentityNode()
69  val beu = LazyModule(new BusErrorUnit(
70    new XSL1BusErrors(), BusErrorUnitParams(0x38010000)
71  ))
72
73  val i_mmio_port = TLTempNode()
74  val d_mmio_port = TLTempNode()
75
76  val misc_l2_pmu = BusPerfMonitor(name = "Misc_L2", enable = !debugOpts.FPGAPlatform) // l1D & l1I & PTW
77  val l2_l3_pmu = BusPerfMonitor(name = "L2_L3", enable = !debugOpts.FPGAPlatform, stat_latency = true)
78  val xbar_l2_buffer = TLBuffer()
79
80  val enbale_tllog = !debugOpts.FPGAPlatform && debugOpts.AlwaysBasicDB
81  val l1d_logger = TLLogger(s"L2_L1D_${coreParams.HartId}", enbale_tllog)
82  val l1i_logger = TLLogger(s"L2_L1I_${coreParams.HartId}", enbale_tllog)
83  val ptw_logger = TLLogger(s"L2_PTW_${coreParams.HartId}", enbale_tllog)
84  val ptw_to_l2_buffer = LazyModule(new TLBuffer)
85  val i_mmio_buffer = LazyModule(new TLBuffer)
86
87  val clint_int_node = IntIdentityNode()
88  val debug_int_node = IntIdentityNode()
89  val plic_int_node = IntIdentityNode()
90
91  val l2cache = coreParams.L2CacheParamsOpt.map(l2param =>
92    LazyModule(new CoupledL2()(new Config((_, _, _) => {
93      case L2ParamKey => l2param.copy(
94          hartId = p(XSCoreParamsKey).HartId,
95          FPGAPlatform = debugOpts.FPGAPlatform
96        )
97      case MaxHartIdBits => p(MaxHartIdBits)
98    })))
99  )
100  val l2_binder = coreParams.L2CacheParamsOpt.map(_ => BankBinder(coreParams.L2NBanks, 64))
101
102  // =========== Connection ============
103  // l2 to l2_binder, then to memory_port
104  l2_binder match {
105    case Some(binder) =>
106      memory_port := l2_l3_pmu := TLClientsMerger() := TLXbar() :=* binder :*= l2cache.get.node
107    case None =>
108      memory_port := l1_xbar
109  }
110
111  mmio_xbar := TLBuffer.chainNode(2) := i_mmio_port
112  mmio_xbar := TLBuffer.chainNode(2) := d_mmio_port
113  beu.node := TLBuffer.chainNode(1) := mmio_xbar
114  mmio_port := TLBuffer() := mmio_xbar
115
116  class L2TopImp(wrapper: LazyModule) extends LazyModuleImp(wrapper) {
117    val beu_errors = IO(Input(chiselTypeOf(beu.module.io.errors)))
118    val reset_vector = IO(new Bundle {
119      val fromTile = Input(UInt(PAddrBits.W))
120      val toCore = Output(UInt(PAddrBits.W))
121    })
122    val hartId = IO(new Bundle() {
123      val fromTile = Input(UInt(64.W))
124      val toCore = Output(UInt(64.W))
125    })
126    val cpu_halt = IO(new Bundle() {
127      val fromCore = Input(Bool())
128      val toTile = Output(Bool())
129    })
130    val debugTopDown = IO(new Bundle() {
131      val robTrueCommit = Input(UInt(64.W))
132      val robHeadPaddr = Flipped(Valid(UInt(36.W)))
133      val l2MissMatch = Output(Bool())
134    })
135    val l2_tlb_req = IO(new TlbRequestIO(nRespDups = 2))
136
137    val resetDelayN = Module(new DelayN(UInt(PAddrBits.W), 5))
138
139    beu.module.io.errors <> beu_errors
140    resetDelayN.io.in := reset_vector.fromTile
141    reset_vector.toCore := resetDelayN.io.out
142    hartId.toCore := hartId.fromTile
143    cpu_halt.toTile := cpu_halt.fromCore
144    dontTouch(hartId)
145    dontTouch(cpu_halt)
146
147    val l2_hint = IO(ValidIO(new L2ToL1Hint())) // TODO: parameterize this
148    if (l2cache.isDefined) {
149      l2_hint := l2cache.get.module.io.l2_hint
150      // debugTopDown <> l2cache.get.module.io.debugTopDown
151      l2cache.get.module.io.debugTopDown.robHeadPaddr := DontCare
152      l2cache.get.module.io.hartId := hartId.fromTile
153      l2cache.get.module.io.debugTopDown.robHeadPaddr := debugTopDown.robHeadPaddr
154      l2cache.get.module.io.debugTopDown.robTrueCommit := debugTopDown.robTrueCommit
155      debugTopDown.l2MissMatch := l2cache.get.module.io.debugTopDown.l2MissMatch
156
157      /* l2 tlb */
158      l2_tlb_req.req.bits := DontCare
159      l2_tlb_req.req.valid := l2cache.get.module.io.l2_tlb_req.req.valid
160      l2_tlb_req.resp.ready := l2cache.get.module.io.l2_tlb_req.resp.ready
161      l2_tlb_req.req.bits.vaddr := l2cache.get.module.io.l2_tlb_req.req.bits.vaddr
162      l2_tlb_req.req.bits.cmd := l2cache.get.module.io.l2_tlb_req.req.bits.cmd
163      l2_tlb_req.req.bits.size := l2cache.get.module.io.l2_tlb_req.req.bits.size
164      l2_tlb_req.req.bits.kill := l2cache.get.module.io.l2_tlb_req.req.bits.kill
165      l2_tlb_req.req.bits.no_translate := l2cache.get.module.io.l2_tlb_req.req.bits.no_translate
166      l2_tlb_req.req_kill := l2cache.get.module.io.l2_tlb_req.req_kill
167      l2cache.get.module.io.l2_tlb_req.resp.valid := l2_tlb_req.resp.valid
168      l2cache.get.module.io.l2_tlb_req.req.ready := l2_tlb_req.req.ready
169      l2cache.get.module.io.l2_tlb_req.resp.bits.paddr.head := l2_tlb_req.resp.bits.paddr.head
170      l2cache.get.module.io.l2_tlb_req.resp.bits.miss := l2_tlb_req.resp.bits.miss
171      l2cache.get.module.io.l2_tlb_req.resp.bits.excp.head <> l2_tlb_req.resp.bits.excp.head
172    } else {
173      l2_hint := 0.U.asTypeOf(l2_hint)
174      debugTopDown <> DontCare
175
176      l2_tlb_req.req.valid := false.B
177      l2_tlb_req.req.bits := DontCare
178      l2_tlb_req.req_kill := DontCare
179      l2_tlb_req.resp.ready := true.B
180      l2cache.get.module.io.l2_tlb_req.req.ready := true.B
181      l2cache.get.module.io.l2_tlb_req.resp.valid := false.B
182      l2cache.get.module.io.l2_tlb_req.resp.bits := DontCare
183    }
184  }
185
186  lazy val module = new L2TopImp(this)
187}