xref: /XiangShan/src/main/scala/top/Top.scala (revision 4f94c0c6a6566aaa01312dd72d05c29ac896b8ab)
1c6d43980SLemover/***************************************************************************************
2c6d43980SLemover* Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences
3f320e0f0SYinan Xu* Copyright (c) 2020-2021 Peng Cheng Laboratory
4c6d43980SLemover*
5c6d43980SLemover* XiangShan is licensed under Mulan PSL v2.
6c6d43980SLemover* You can use this software according to the terms and conditions of the Mulan PSL v2.
7c6d43980SLemover* You may obtain a copy of Mulan PSL v2 at:
8c6d43980SLemover*          http://license.coscl.org.cn/MulanPSL2
9c6d43980SLemover*
10c6d43980SLemover* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
11c6d43980SLemover* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
12c6d43980SLemover* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
13c6d43980SLemover*
14c6d43980SLemover* See the Mulan PSL v2 for more details.
15c6d43980SLemover***************************************************************************************/
16c6d43980SLemover
178b037849SYinan Xupackage top
188b037849SYinan Xu
198b037849SYinan Xuimport chisel3._
208b037849SYinan Xuimport chisel3.util._
218b037849SYinan Xuimport xiangshan._
2294c92d92SYinan Xuimport utils._
238b037849SYinan Xuimport system._
24d4aca96cSlqreimport device._
258b037849SYinan Xuimport chisel3.stage.ChiselGeneratorAnnotation
262225d46eSJiawei Linimport chipsalliance.rocketchip.config._
27a1ea7f76SJiawei Linimport device.{AXI4Plic, DebugModule, TLTimer}
288b037849SYinan Xuimport freechips.rocketchip.diplomacy._
298b037849SYinan Xuimport freechips.rocketchip.tilelink._
308b037849SYinan Xuimport freechips.rocketchip.amba.axi4._
31afcc4f2aSJiawei Linimport freechips.rocketchip.devices.tilelink._
322e3a956eSLinJiaweiimport freechips.rocketchip.diplomaticobjectmodel.logicaltree.GenericLogicalTreeNode
33afcc4f2aSJiawei Linimport freechips.rocketchip.interrupts._
34d4aca96cSlqreimport freechips.rocketchip.jtag.JTAGIO
352e3a956eSLinJiaweiimport freechips.rocketchip.tile.{BusErrorUnit, BusErrorUnitParams, XLen}
361a2cf152SYinan Xuimport freechips.rocketchip.tilelink
37afcc4f2aSJiawei Linimport freechips.rocketchip.util.{ElaborationArtefacts, HasRocketChipStageUtils}
38a1ea7f76SJiawei Linimport huancun.debug.TLLogger
39a1ea7f76SJiawei Linimport huancun.{HCCacheParamsKey, HuanCun}
40d4aca96cSlqreimport freechips.rocketchip.devices.debug.{DebugIO, ResetCtrlIO}
41d4aca96cSlqre
422225d46eSJiawei Linclass XSCoreWithL2()(implicit p: Parameters) extends LazyModule
432225d46eSJiawei Lin  with HasXSParameter with HasSoCParameter {
44afcc4f2aSJiawei Lin  private val core = LazyModule(new XSCore)
45*4f94c0c6SJiawei Lin  private val busPMU = BusPerfMonitor(enable = !debugOpts.FPGAPlatform)
46*4f94c0c6SJiawei Lin  private val l2cacheOpt = coreParams.L2CacheParamsOpt.map(l2param =>
47a1ea7f76SJiawei Lin    LazyModule(new HuanCun()(new Config((_, _, _) => {
48*4f94c0c6SJiawei Lin      case HCCacheParamsKey => l2param
49a1ea7f76SJiawei Lin    })))
50*4f94c0c6SJiawei Lin  )
51*4f94c0c6SJiawei Lin  // (icache/ptw/dcache) => l2 or mem
52*4f94c0c6SJiawei Lin  private val l1_xbar = TLXbar()
539d5a2027SYinan Xu
549d5a2027SYinan Xu  val memory_port = TLIdentityNode()
5594c92d92SYinan Xu  val uncache = TLXbar()
566c4d7a40SYinan Xu
57*4f94c0c6SJiawei Lin  if (coreParams.dcacheParametersOpt.nonEmpty) {
58*4f94c0c6SJiawei Lin    busPMU := TLLogger(s"L2_L1D_$hardId") := core.memBlock.dcache.clientNode
599d5a2027SYinan Xu  }
60*4f94c0c6SJiawei Lin  busPMU := core.frontend.icache.clientNode
61*4f94c0c6SJiawei Lin  if (!coreParams.softPTW) {
62*4f94c0c6SJiawei Lin    busPMU := core.ptw.node
639d5a2027SYinan Xu  }
64*4f94c0c6SJiawei Lin  l1_xbar :=* busPMU
65*4f94c0c6SJiawei Lin  l2cacheOpt match {
66*4f94c0c6SJiawei Lin    case Some(l2) =>
67*4f94c0c6SJiawei Lin      memory_port := l2.node := l1_xbar
68*4f94c0c6SJiawei Lin    case None =>
69*4f94c0c6SJiawei Lin      memory_port := l1_xbar
709d5a2027SYinan Xu  }
716c4d7a40SYinan Xu
7294c92d92SYinan Xu  uncache := TLBuffer() := core.frontend.instrUncache.clientNode
7394c92d92SYinan Xu  uncache := TLBuffer() := core.memBlock.uncache.clientNode
746c4d7a40SYinan Xu
7594c92d92SYinan Xu  lazy val module = new LazyModuleImp(this) {
766c4d7a40SYinan Xu    val io = IO(new Bundle {
776c4d7a40SYinan Xu      val hartId = Input(UInt(64.W))
786c4d7a40SYinan Xu      val externalInterrupt = new ExternalInterruptIO
794e3ce935Sljw      val l1plus_error, icache_error, dcache_error = new L1CacheErrorInfo
806c4d7a40SYinan Xu    })
816c4d7a40SYinan Xu
8294c92d92SYinan Xu    core.module.io.hartId := io.hartId
8394c92d92SYinan Xu    core.module.io.externalInterrupt := io.externalInterrupt
84a1ea7f76SJiawei Lin
8594c92d92SYinan Xu    io.l1plus_error <> core.module.io.l1plus_error
8694c92d92SYinan Xu    io.icache_error <> core.module.io.icache_error
8794c92d92SYinan Xu    io.dcache_error <> core.module.io.dcache_error
886c4d7a40SYinan Xu
892225d46eSJiawei Lin    val core_reset_gen = Module(new ResetGen(1, !debugOpts.FPGAPlatform))
9094c92d92SYinan Xu    core.module.reset := core_reset_gen.io.out
9194c92d92SYinan Xu
922225d46eSJiawei Lin    val l2_reset_gen = Module(new ResetGen(1, !debugOpts.FPGAPlatform))
93*4f94c0c6SJiawei Lin    l2cacheOpt.foreach( _.module.reset := l2_reset_gen.io.out)
9494c92d92SYinan Xu  }
959d5a2027SYinan Xu}
966c4d7a40SYinan Xu
97afcc4f2aSJiawei Linabstract class BaseXSSoc()(implicit p: Parameters) extends LazyModule
98afcc4f2aSJiawei Lin  with HasSoCParameter
99afcc4f2aSJiawei Lin  with BindingScope
100afcc4f2aSJiawei Lin{
1018b037849SYinan Xu  val bankedNode = BankBinder(L3NBanks, L3BlockSize)
1028b037849SYinan Xu  val peripheralXbar = TLXbar()
1038b037849SYinan Xu  val l3_xbar = TLXbar()
104afcc4f2aSJiawei Lin  lazy val dts = DTS(bindingTree)
1054f0a2459Swakafa  lazy val json = JSON(bindingTree)
1068b037849SYinan Xu}
1078b037849SYinan Xu
1088b037849SYinan Xu// We adapt the following three traits from rocket-chip.
1098b037849SYinan Xu// Source: rocket-chip/src/main/scala/subsystem/Ports.scala
1108b037849SYinan Xutrait HaveSlaveAXI4Port {
1118b037849SYinan Xu  this: BaseXSSoc =>
1128b037849SYinan Xu
1138130d625Srvcoresjw  val idBits = 14
1148b037849SYinan Xu
1158b037849SYinan Xu  val l3FrontendAXI4Node = AXI4MasterNode(Seq(AXI4MasterPortParameters(
1168b037849SYinan Xu    Seq(AXI4MasterParameters(
1178b037849SYinan Xu      name = "dma",
1188b037849SYinan Xu      id = IdRange(0, 1 << idBits)
1198b037849SYinan Xu    ))
1208b037849SYinan Xu  )))
1218b037849SYinan Xu  private val errorDevice = LazyModule(new TLError(
1228b037849SYinan Xu    params = DevNullParams(
1238b037849SYinan Xu      address = Seq(AddressSet(0x0, 0x7fffffffL)),
1248b037849SYinan Xu      maxAtomic = 8,
1258b037849SYinan Xu      maxTransfer = 64),
1262225d46eSJiawei Lin    beatBytes = L3InnerBusWidth / 8
1278b037849SYinan Xu  ))
1288b037849SYinan Xu  private val error_xbar = TLXbar()
1298b037849SYinan Xu
1308b037849SYinan Xu  error_xbar :=
1318130d625Srvcoresjw    TLWidthWidget(16) :=
1328b037849SYinan Xu    AXI4ToTL() :=
1338b037849SYinan Xu    AXI4UserYanker(Some(1)) :=
1348b037849SYinan Xu    AXI4Fragmenter() :=
1358b037849SYinan Xu    AXI4IdIndexer(1) :=
1368b037849SYinan Xu    l3FrontendAXI4Node
1378b037849SYinan Xu  errorDevice.node := error_xbar
1388b037849SYinan Xu  l3_xbar :=
1398b037849SYinan Xu    TLBuffer() :=
1408b037849SYinan Xu    error_xbar
1418b037849SYinan Xu
1428b037849SYinan Xu  val dma = InModuleBody {
1438b037849SYinan Xu    l3FrontendAXI4Node.makeIOs()
1448b037849SYinan Xu  }
1458b037849SYinan Xu}
1468b037849SYinan Xu
1478b037849SYinan Xutrait HaveAXI4MemPort {
1488b037849SYinan Xu  this: BaseXSSoc =>
149afcc4f2aSJiawei Lin  val device = new MemoryDevice
1508b037849SYinan Xu  // 40-bit physical address
1518b037849SYinan Xu  val memRange = AddressSet(0x00000000L, 0xffffffffffL).subtract(AddressSet(0x0L, 0x7fffffffL))
152329e267dSYinan Xu  val memAXI4SlaveNode = AXI4SlaveNode(Seq(
1538b037849SYinan Xu    AXI4SlavePortParameters(
1548b037849SYinan Xu      slaves = Seq(
1558b037849SYinan Xu        AXI4SlaveParameters(
1568b037849SYinan Xu          address = memRange,
1578b037849SYinan Xu          regionType = RegionType.UNCACHED,
1588b037849SYinan Xu          executable = true,
1598b037849SYinan Xu          supportsRead = TransferSizes(1, L3BlockSize),
1608b037849SYinan Xu          supportsWrite = TransferSizes(1, L3BlockSize),
161afcc4f2aSJiawei Lin          interleavedId = Some(0),
162afcc4f2aSJiawei Lin          resources = device.reg("mem")
1638b037849SYinan Xu        )
1648b037849SYinan Xu      ),
1652225d46eSJiawei Lin      beatBytes = L3OuterBusWidth / 8
1668b037849SYinan Xu    )
167329e267dSYinan Xu  ))
1688b037849SYinan Xu
169329e267dSYinan Xu  val mem_xbar = TLXbar()
170329e267dSYinan Xu  mem_xbar :=* TLBuffer() :=* TLCacheCork() :=* bankedNode
171329e267dSYinan Xu  memAXI4SlaveNode :=
172329e267dSYinan Xu    AXI4UserYanker() :=
173329e267dSYinan Xu    AXI4Deinterleaver(L3BlockSize) :=
174329e267dSYinan Xu    TLToAXI4() :=
1752225d46eSJiawei Lin    TLWidthWidget(L3OuterBusWidth / 8) :=
176329e267dSYinan Xu    mem_xbar
1778b037849SYinan Xu
1788b037849SYinan Xu  val memory = InModuleBody {
1798b037849SYinan Xu    memAXI4SlaveNode.makeIOs()
1808b037849SYinan Xu  }
1818b037849SYinan Xu}
1828b037849SYinan Xu
1838b037849SYinan Xu
1848b037849SYinan Xutrait HaveAXI4PeripheralPort { this: BaseXSSoc =>
185d4aca96cSlqre  // on-chip devices: 0x3800_0000 - 0x3fff_ffff 0x0000_0000 - 0x0000_0fff
1868b037849SYinan Xu  val onChipPeripheralRange = AddressSet(0x38000000L, 0x07ffffffL)
187afcc4f2aSJiawei Lin  val uartRange = AddressSet(0x40600000, 0xf)
188afcc4f2aSJiawei Lin  val uartDevice = new SimpleDevice("serial", Seq("xilinx,uartlite"))
189afcc4f2aSJiawei Lin  val uartParams = AXI4SlaveParameters(
190afcc4f2aSJiawei Lin    address = Seq(uartRange),
191afcc4f2aSJiawei Lin    regionType = RegionType.UNCACHED,
192afcc4f2aSJiawei Lin    supportsRead = TransferSizes(1, 8),
193afcc4f2aSJiawei Lin    supportsWrite = TransferSizes(1, 8),
194afcc4f2aSJiawei Lin    resources = uartDevice.reg
195afcc4f2aSJiawei Lin  )
196afcc4f2aSJiawei Lin  val peripheralRange = AddressSet(
197afcc4f2aSJiawei Lin    0x0, 0x7fffffff
198afcc4f2aSJiawei Lin  ).subtract(onChipPeripheralRange).flatMap(x => x.subtract(uartRange))
1998b037849SYinan Xu  val peripheralNode = AXI4SlaveNode(Seq(AXI4SlavePortParameters(
2008b037849SYinan Xu    Seq(AXI4SlaveParameters(
2018b037849SYinan Xu      address = peripheralRange,
2028b037849SYinan Xu      regionType = RegionType.UNCACHED,
2038b037849SYinan Xu      supportsRead = TransferSizes(1, 8),
2048b037849SYinan Xu      supportsWrite = TransferSizes(1, 8),
2058b037849SYinan Xu      interleavedId = Some(0)
206afcc4f2aSJiawei Lin    ), uartParams),
2078b037849SYinan Xu    beatBytes = 8
2088b037849SYinan Xu  )))
2098b037849SYinan Xu
2108b037849SYinan Xu  peripheralNode :=
2118b037849SYinan Xu    AXI4UserYanker() :=
2129d4d50e0SYinan Xu    AXI4Deinterleaver(8) :=
2138b037849SYinan Xu    TLToAXI4() :=
2148b037849SYinan Xu    peripheralXbar
2158b037849SYinan Xu
2168b037849SYinan Xu  val peripheral = InModuleBody {
2178b037849SYinan Xu    peripheralNode.makeIOs()
2188b037849SYinan Xu  }
2198b037849SYinan Xu
2208b037849SYinan Xu}
2218b037849SYinan Xu
2222225d46eSJiawei Linclass XSTop()(implicit p: Parameters) extends XSTopWithoutDMA
2232225d46eSJiawei Lin  with HaveSlaveAXI4Port
2248b037849SYinan Xu
2252225d46eSJiawei Linclass XSTopWithoutDMA()(implicit p: Parameters) extends BaseXSSoc()
2268b037849SYinan Xu  with HaveAXI4MemPort
2278b037849SYinan Xu  with HaveAXI4PeripheralPort
2288b037849SYinan Xu{
229afcc4f2aSJiawei Lin  ResourceBinding {
230afcc4f2aSJiawei Lin    val width = ResourceInt(2)
231afcc4f2aSJiawei Lin    val model = "freechips,rocketchip-unknown"
232afcc4f2aSJiawei Lin    Resource(ResourceAnchors.root, "model").bind(ResourceString(model))
233afcc4f2aSJiawei Lin    Resource(ResourceAnchors.root, "compat").bind(ResourceString(model + "-dev"))
234afcc4f2aSJiawei Lin    Resource(ResourceAnchors.soc, "compat").bind(ResourceString(model + "-soc"))
235afcc4f2aSJiawei Lin    Resource(ResourceAnchors.root, "width").bind(width)
236afcc4f2aSJiawei Lin    Resource(ResourceAnchors.soc, "width").bind(width)
237afcc4f2aSJiawei Lin    Resource(ResourceAnchors.cpus, "width").bind(ResourceInt(1))
238afcc4f2aSJiawei Lin    def bindManagers(xbar: TLNexusNode) = {
239afcc4f2aSJiawei Lin      ManagerUnification(xbar.edges.in.head.manager.managers).foreach{ manager =>
240afcc4f2aSJiawei Lin        manager.resources.foreach(r => r.bind(manager.toResource))
241afcc4f2aSJiawei Lin      }
242afcc4f2aSJiawei Lin    }
243afcc4f2aSJiawei Lin    bindManagers(l3_xbar.asInstanceOf[TLNexusNode])
244afcc4f2aSJiawei Lin    bindManagers(peripheralXbar.asInstanceOf[TLNexusNode])
245afcc4f2aSJiawei Lin  }
2468b037849SYinan Xu
2472225d46eSJiawei Lin  println(s"FPGASoC cores: $NumCores banks: $L3NBanks block size: $L3BlockSize bus size: $L3OuterBusWidth")
2488b037849SYinan Xu
2492225d46eSJiawei Lin  val core_with_l2 = soc.cores.map(coreParams =>
2502225d46eSJiawei Lin    LazyModule(new XSCoreWithL2()(p.alterPartial({
2512225d46eSJiawei Lin      case XSCoreParamsKey => coreParams
2522225d46eSJiawei Lin    })))
2532225d46eSJiawei Lin  )
2548b037849SYinan Xu
2558b037849SYinan Xu  for (i <- 0 until NumCores) {
25694c92d92SYinan Xu    peripheralXbar := TLBuffer() := core_with_l2(i).uncache
2571f0e2dc7SJiawei Lin    val l2_l3_pmu = BusPerfMonitor(enable = true)
2581f0e2dc7SJiawei Lin    l3_xbar := TLBuffer() := TLLogger(s"L3_L2_$i") := l2_l3_pmu := core_with_l2(i).memory_port
2598b037849SYinan Xu  }
2608b037849SYinan Xu
261afcc4f2aSJiawei Lin  val clint = LazyModule(new CLINT(CLINTParams(0x38000000L), 8))
2628b037849SYinan Xu  clint.node := peripheralXbar
2638b037849SYinan Xu
264afcc4f2aSJiawei Lin  val clintIntSinks = Array.fill(NumCores){
265afcc4f2aSJiawei Lin    val clintSink = LazyModule(new IntSinkNodeToModule(2))
266afcc4f2aSJiawei Lin    clintSink.sinkNode := clint.intnode
267afcc4f2aSJiawei Lin    clintSink
268afcc4f2aSJiawei Lin  }
269afcc4f2aSJiawei Lin
2702e3a956eSLinJiawei  val fakeTreeNode = new GenericLogicalTreeNode
2712e3a956eSLinJiawei  val beu = LazyModule(
2722e3a956eSLinJiawei    new BusErrorUnit(new XSL1BusErrors(NumCores), BusErrorUnitParams(0x38010000), fakeTreeNode))
2732e3a956eSLinJiawei  beu.node := peripheralXbar
2742e3a956eSLinJiawei
275afcc4f2aSJiawei Lin  class IntSinkNodeToModule(val sinks: Int)(implicit p: Parameters) extends LazyModule {
276afcc4f2aSJiawei Lin    val sinkNode = IntSinkNode(IntSinkPortSimple(1, sinks))
2772e3a956eSLinJiawei    lazy val module = new LazyModuleImp(this){
278afcc4f2aSJiawei Lin      val out = IO(Output(Vec(sinks, Bool())))
279afcc4f2aSJiawei Lin      out.zip(sinkNode.in.head._1).foreach{ case (o, i) => o := i }
2802e3a956eSLinJiawei    }
2812e3a956eSLinJiawei  }
2822e3a956eSLinJiawei
283afcc4f2aSJiawei Lin  class IntSourceNodeToModule(val num: Int)(implicit p: Parameters) extends LazyModule {
284afcc4f2aSJiawei Lin    val sourceNode = IntSourceNode(IntSourcePortSimple(num, ports = 1, sources = 1))
285afcc4f2aSJiawei Lin    lazy val module = new LazyModuleImp(this){
286afcc4f2aSJiawei Lin      val in = IO(Input(Vec(num, Bool())))
287afcc4f2aSJiawei Lin      in.zip(sourceNode.out.head._1).foreach{ case (i, s) => s := i }
288afcc4f2aSJiawei Lin    }
289afcc4f2aSJiawei Lin  }
290afcc4f2aSJiawei Lin
291afcc4f2aSJiawei Lin  val plic = LazyModule(new TLPLIC(PLICParams(0x3c000000L), 8))
292afcc4f2aSJiawei Lin  val plicSource = LazyModule(new IntSourceNodeToModule(NrExtIntr))
293afcc4f2aSJiawei Lin  val plicIntSinks = Array.fill(NumCores){
294afcc4f2aSJiawei Lin    val plicSink = LazyModule(new IntSinkNodeToModule(1))
295afcc4f2aSJiawei Lin    plicSink.sinkNode := plic.intnode
296afcc4f2aSJiawei Lin    plicSink
297afcc4f2aSJiawei Lin  }
298afcc4f2aSJiawei Lin  plic.intnode := beu.intNode
299afcc4f2aSJiawei Lin  plic.intnode := plicSource.sourceNode
300afcc4f2aSJiawei Lin
301afcc4f2aSJiawei Lin  plic.node := peripheralXbar
3028b037849SYinan Xu
303*4f94c0c6SJiawei Lin  val l3cacheOpt = soc.L3CacheParamsOpt.map(l3param =>
304*4f94c0c6SJiawei Lin    LazyModule(new HuanCun()(new Config((_, _, _) => {
305*4f94c0c6SJiawei Lin      case HCCacheParamsKey => l3param
306a1ea7f76SJiawei Lin    })))
307*4f94c0c6SJiawei Lin  )
308*4f94c0c6SJiawei Lin  val l3_mem_pmu = BusPerfMonitor(enable = !debugOpts.FPGAPlatform)
309a1ea7f76SJiawei Lin
310*4f94c0c6SJiawei Lin  l3cacheOpt match {
311*4f94c0c6SJiawei Lin    case Some(l3) =>
312*4f94c0c6SJiawei Lin      bankedNode :*= TLLogger("MEM_L3") :*= l3_mem_pmu :*= l3.node :*= TLBuffer() :*= l3_xbar
313*4f94c0c6SJiawei Lin    case None => bankedNode :*= TLIgnoreNode() :*= l3_xbar
3149d5a2027SYinan Xu  }
3158b037849SYinan Xu
316d4aca96cSlqre  val debugModule = LazyModule(new DebugModule(NumCores)(p))
317d4aca96cSlqre  debugModule.debug.node := peripheralXbar
3185ef7374fSLi Qianruo  val debugIntSink = Array.fill(NumCores){
3195ef7374fSLi Qianruo    val debugSink = LazyModule(new IntSinkNodeToModule(1))
3205ef7374fSLi Qianruo    debugSink.sinkNode := debugModule.debug.dmOuter.dmOuter.intnode
3215ef7374fSLi Qianruo    debugSink
3225ef7374fSLi Qianruo  }
323d4aca96cSlqre  debugModule.debug.dmInner.dmInner.sb2tlOpt.foreach { sb2tl  =>
324d4aca96cSlqre    l3_xbar := TLBuffer() := TLWidthWidget(1) := sb2tl.node
3258b037849SYinan Xu  }
3268b037849SYinan Xu
32794c92d92SYinan Xu  lazy val module = new LazyRawModuleImp(this) {
328afcc4f2aSJiawei Lin    ElaborationArtefacts.add("dts", dts)
3294f0a2459Swakafa    ElaborationArtefacts.add("graphml", graphML)
3304f0a2459Swakafa    ElaborationArtefacts.add("json", json)
3314f0a2459Swakafa    ElaborationArtefacts.add("plusArgs", freechips.rocketchip.util.PlusArgArtefacts.serialize_cHeader())
3324f0a2459Swakafa
3338b037849SYinan Xu    val io = IO(new Bundle {
33494c92d92SYinan Xu      val clock = Input(Bool())
33594c92d92SYinan Xu      val reset = Input(Bool())
3368130d625Srvcoresjw      val sram_config = Input(UInt(5.W))
3378130d625Srvcoresjw      val osc_clock = Input(Bool())
3388130d625Srvcoresjw      val pll_output = Output(UInt(14.W))
3398b037849SYinan Xu      val extIntrs = Input(UInt(NrExtIntr.W))
3408b037849SYinan Xu      // val meip = Input(Vec(NumCores, Bool()))
3412225d46eSJiawei Lin      val ila = if(debugOpts.FPGAPlatform && EnableILA) Some(Output(new ILABundle)) else None
342d4aca96cSlqre      val systemjtag = new Bundle {
343d4aca96cSlqre        val jtag = Flipped(new JTAGIO(hasTRSTn = false))
344d4aca96cSlqre        val reset = Input(Bool()) // No reset allowed on top
345d4aca96cSlqre        val mfr_id = Input(UInt(11.W))
346d4aca96cSlqre        val part_number = Input(UInt(16.W))
347d4aca96cSlqre        val version = Input(UInt(4.W))
348d4aca96cSlqre      }
349d4aca96cSlqre      // val resetCtrl = new ResetCtrlIO(NumCores)(p)
3508b037849SYinan Xu    })
3518130d625Srvcoresjw    io.pll_output := DontCare
3528130d625Srvcoresjw    dontTouch(io.sram_config)
3538130d625Srvcoresjw    dontTouch(io.osc_clock)
3548130d625Srvcoresjw    dontTouch(io.pll_output)
35594c92d92SYinan Xu    childClock := io.clock.asClock()
3568b037849SYinan Xu
35794c92d92SYinan Xu    withClockAndReset(childClock, io.reset) {
3582225d46eSJiawei Lin      val resetGen = Module(new ResetGen(1, !debugOpts.FPGAPlatform))
35994c92d92SYinan Xu      resetGen.suggestName("top_reset_gen")
360d4aca96cSlqre      childReset := resetGen.io.out | debugModule.module.io.debugIO.ndreset
36194c92d92SYinan Xu    }
36294c92d92SYinan Xu
36394c92d92SYinan Xu    withClockAndReset(childClock, childReset) {
364afcc4f2aSJiawei Lin      plicSource.module.in := io.extIntrs.asBools()
365c0bc1ee4SYinan Xu
3668b037849SYinan Xu      for (i <- 0 until NumCores) {
3672225d46eSJiawei Lin        val core_reset_gen = Module(new ResetGen(1, !debugOpts.FPGAPlatform))
36894c92d92SYinan Xu        core_reset_gen.suggestName(s"core_${i}_reset_gen")
36994c92d92SYinan Xu        core_with_l2(i).module.reset := core_reset_gen.io.out
3706c4d7a40SYinan Xu        core_with_l2(i).module.io.hartId := i.U
371afcc4f2aSJiawei Lin        core_with_l2(i).module.io.externalInterrupt.msip := clintIntSinks(i).module.out(0)
372afcc4f2aSJiawei Lin        core_with_l2(i).module.io.externalInterrupt.mtip := clintIntSinks(i).module.out(1)
373afcc4f2aSJiawei Lin        core_with_l2(i).module.io.externalInterrupt.meip := plicIntSinks(i).module.out(0)
3745ef7374fSLi Qianruo        core_with_l2(i).module.io.externalInterrupt.debug := debugIntSink(i).module.out(0)
375c0bc1ee4SYinan Xu        beu.module.io.errors.l1plus(i) := core_with_l2(i).module.io.l1plus_error
376c0bc1ee4SYinan Xu        beu.module.io.errors.icache(i) := core_with_l2(i).module.io.icache_error
377c0bc1ee4SYinan Xu        beu.module.io.errors.dcache(i) := core_with_l2(i).module.io.dcache_error
3788b037849SYinan Xu      }
3798b037849SYinan Xu
380*4f94c0c6SJiawei Lin      if (l3cacheOpt.nonEmpty) {
3812225d46eSJiawei Lin        val l3_reset_gen = Module(new ResetGen(1, !debugOpts.FPGAPlatform))
38294c92d92SYinan Xu        l3_reset_gen.suggestName("l3_reset_gen")
383*4f94c0c6SJiawei Lin        l3cacheOpt.get.module.reset := l3_reset_gen.io.out
38494c92d92SYinan Xu      }
385330595dfSJiawei Lin      // TODO: wrap this in a module
386330595dfSJiawei Lin      val freq = 100
387330595dfSJiawei Lin      val cnt = RegInit(freq.U)
388330595dfSJiawei Lin      val tick = cnt === 0.U
389330595dfSJiawei Lin      cnt := Mux(tick, freq.U, cnt - 1.U)
390330595dfSJiawei Lin      clint.module.io.rtcTick := tick
391d4aca96cSlqre
392d4aca96cSlqre      debugModule.module.io.resetCtrl.hartIsInReset.foreach {x => x := childReset.asBool() }
393d4aca96cSlqre      debugModule.module.io.clock := io.clock
394d4aca96cSlqre      debugModule.module.io.reset := io.reset
395d4aca96cSlqre
396d4aca96cSlqre      debugModule.module.io.debugIO.reset := io.systemjtag.reset // TODO: use synchronizer?
397d4aca96cSlqre      debugModule.module.io.debugIO.clock := childClock
398d4aca96cSlqre      debugModule.module.io.debugIO.dmactiveAck  := debugModule.module.io.debugIO.dmactive // TODO: delay 3 cycles?
399d4aca96cSlqre      // jtag connector
400d4aca96cSlqre      debugModule.module.io.debugIO.systemjtag.foreach { x =>
401d4aca96cSlqre        x.jtag <> io.systemjtag.jtag
402d4aca96cSlqre        x.reset  := io.systemjtag.reset
403d4aca96cSlqre        x.mfr_id := io.systemjtag.mfr_id
404d4aca96cSlqre        x.part_number := io.systemjtag.part_number
405d4aca96cSlqre        x.version := io.systemjtag.version
406d4aca96cSlqre      }
4078b037849SYinan Xu    }
4088b037849SYinan Xu  }
4099d5a2027SYinan Xu}
4108b037849SYinan Xu
411afcc4f2aSJiawei Linobject TopMain extends App with HasRocketChipStageUtils {
4128b037849SYinan Xu  override def main(args: Array[String]): Unit = {
41345c767e3SLinJiawei    val (config, firrtlOpts) = ArgParser.parse(args)
41445c767e3SLinJiawei    XiangShanStage.execute(firrtlOpts, Seq(
4158b037849SYinan Xu      ChiselGeneratorAnnotation(() => {
41645c767e3SLinJiawei        val soc = LazyModule(new XSTop()(config))
4178b037849SYinan Xu        soc.module
4188b037849SYinan Xu      })
4198b037849SYinan Xu    ))
420afcc4f2aSJiawei Lin    ElaborationArtefacts.files.foreach{ case (extension, contents) =>
421afcc4f2aSJiawei Lin      writeOutputFile("./build", s"XSTop.${extension}", contents())
422afcc4f2aSJiawei Lin    }
4238b037849SYinan Xu  }
4248b037849SYinan Xu}
425