xref: /XiangShan/src/main/scala/top/Top.scala (revision 30f35717e23156cb95b30a36db530384545b48a4)
1/***************************************************************************************
2* Copyright (c) 2024 Beijing Institute of Open Source Chip (BOSC)
3* Copyright (c) 2020-2024 Institute of Computing Technology, Chinese Academy of Sciences
4* Copyright (c) 2020-2021 Peng Cheng Laboratory
5*
6* XiangShan is licensed under Mulan PSL v2.
7* You can use this software according to the terms and conditions of the Mulan PSL v2.
8* You may obtain a copy of Mulan PSL v2 at:
9*          http://license.coscl.org.cn/MulanPSL2
10*
11* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
12* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
13* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
14*
15* See the Mulan PSL v2 for more details.
16***************************************************************************************/
17
18package top
19
20import chisel3._
21import chisel3.util._
22import chisel3.experimental.dataview._
23import difftest.DifftestModule
24import xiangshan._
25import utils._
26import utility._
27import utility.sram.SramBroadcastBundle
28import huancun.{HCCacheParameters, HCCacheParamsKey, HuanCun, PrefetchRecv, TPmetaResp}
29import coupledL2.EnableCHI
30import coupledL2.tl2chi.CHILogger
31import openLLC.{OpenLLC, OpenLLCParamKey, OpenNCB}
32import openLLC.TargetBinder._
33import cc.xiangshan.openncb._
34import system._
35import device._
36import chisel3.stage.ChiselGeneratorAnnotation
37import org.chipsalliance.cde.config._
38import freechips.rocketchip.devices.debug.DebugModuleKey
39import freechips.rocketchip.diplomacy._
40import freechips.rocketchip.tile._
41import freechips.rocketchip.tilelink._
42import freechips.rocketchip.interrupts._
43import freechips.rocketchip.amba.axi4._
44import freechips.rocketchip.jtag.JTAGIO
45import chisel3.experimental.{annotate, ChiselAnnotation}
46import sifive.enterprise.firrtl.NestedPrefixModulesAnnotation
47import scala.collection.mutable.{Map}
48
49import difftest.common.DifftestWiring
50import difftest.util.Profile
51
52abstract class BaseXSSoc()(implicit p: Parameters) extends LazyModule
53  with BindingScope
54{
55  // val misc = LazyModule(new SoCMisc())
56  lazy val dts = DTS(bindingTree)
57  lazy val json = JSON(bindingTree)
58}
59
60class XSTop()(implicit p: Parameters) extends BaseXSSoc() with HasSoCParameter
61{
62  val nocMisc = if (enableCHI) Some(LazyModule(new MemMisc())) else None
63  val socMisc = if (!enableCHI) Some(LazyModule(new SoCMisc())) else None
64  val misc: MemMisc = if (enableCHI) nocMisc.get else socMisc.get
65
66  ResourceBinding {
67    val width = ResourceInt(2)
68    val model = "xiangshan," + os.read(os.resource / "publishVersion")
69    val compatible = "freechips,rocketchip-unknown"
70    Resource(ResourceAnchors.root, "model").bind(ResourceString(model))
71    Resource(ResourceAnchors.root, "compat").bind(ResourceString(compatible + "-dev"))
72    Resource(ResourceAnchors.soc, "compat").bind(ResourceString(compatible + "-soc"))
73    Resource(ResourceAnchors.root, "width").bind(width)
74    Resource(ResourceAnchors.soc, "width").bind(width)
75    Resource(ResourceAnchors.cpus, "width").bind(ResourceInt(1))
76    def bindManagers(xbar: TLNexusNode) = {
77      ManagerUnification(xbar.edges.in.head.manager.managers).foreach{ manager =>
78        manager.resources.foreach(r => r.bind(manager.toResource))
79      }
80    }
81    if (!enableCHI) {
82      bindManagers(misc.l3_xbar.get.asInstanceOf[TLNexusNode])
83      bindManagers(misc.peripheralXbar.get.asInstanceOf[TLNexusNode])
84    }
85  }
86
87  println(s"FPGASoC cores: $NumCores banks: $L3NBanks block size: $L3BlockSize bus size: $L3OuterBusWidth")
88
89  val core_with_l2 = tiles.map(coreParams =>
90    LazyModule(new XSTile()(p.alter((site, here, up) => {
91      case XSCoreParamsKey => coreParams
92      case PerfCounterOptionsKey => up(PerfCounterOptionsKey).copy(perfDBHartID = coreParams.HartId)
93    })))
94  )
95
96  val l3cacheOpt = soc.L3CacheParamsOpt.map(l3param =>
97    LazyModule(new HuanCun()(new Config((_, _, _) => {
98      case HCCacheParamsKey => l3param.copy(
99        hartIds = tiles.map(_.HartId),
100        FPGAPlatform = debugOpts.FPGAPlatform
101      )
102      case MaxHartIdBits => p(MaxHartIdBits)
103      case LogUtilsOptionsKey => p(LogUtilsOptionsKey)
104      case PerfCounterOptionsKey => p(PerfCounterOptionsKey)
105    })))
106  )
107
108  val chi_llcBridge_opt = Option.when(enableCHI)(
109    LazyModule(new OpenNCB()(p.alter((site, here, up) => {
110      case NCBParametersKey => new NCBParameters(
111        outstandingDepth    = 64,
112        axiMasterOrder      = EnumAXIMasterOrder.WriteAddress,
113        readCompDMT         = false,
114        writeCancelable     = false,
115        writeNoError        = true,
116        axiBurstAlwaysIncr  = true,
117        chiDataCheck        = EnumCHIDataCheck.OddParity
118      )
119    })))
120  )
121
122  val chi_mmioBridge_opt = Seq.fill(NumCores)(Option.when(enableCHI)(
123    LazyModule(new OpenNCB()(p.alter((site, here, up) => {
124      case NCBParametersKey => new NCBParameters(
125        outstandingDepth            = 32,
126        axiMasterOrder              = EnumAXIMasterOrder.None,
127        readCompDMT                 = false,
128        writeCancelable             = false,
129        writeNoError                = true,
130        asEndpoint                  = false,
131        acceptOrderEndpoint         = true,
132        acceptMemAttrDevice         = true,
133        readReceiptAfterAcception   = true,
134        axiBurstAlwaysIncr          = true,
135        chiDataCheck                = EnumCHIDataCheck.OddParity
136      )
137    })))
138  ))
139
140  // receive all prefetch req from cores
141  val memblock_pf_recv_nodes: Seq[Option[BundleBridgeSink[PrefetchRecv]]] = core_with_l2.map(_.core_l3_pf_port).map{
142    x => x.map(_ => BundleBridgeSink(Some(() => new PrefetchRecv)))
143  }
144
145  val l3_pf_sender_opt = soc.L3CacheParamsOpt.getOrElse(HCCacheParameters()).prefetch match {
146    case Some(pf) => Some(BundleBridgeSource(() => new PrefetchRecv))
147    case None => None
148  }
149  val nmiIntNode = IntSourceNode(IntSourcePortSimple(1, NumCores, (new NonmaskableInterruptIO).elements.size))
150  val nmi = InModuleBody(nmiIntNode.makeIOs())
151
152  for (i <- 0 until NumCores) {
153    core_with_l2(i).clint_int_node := misc.clint.intnode
154    core_with_l2(i).plic_int_node :*= misc.plic.intnode
155    core_with_l2(i).debug_int_node := misc.debugModule.debug.dmOuter.dmOuter.intnode
156    core_with_l2(i).nmi_int_node := nmiIntNode
157    misc.plic.intnode := IntBuffer() := core_with_l2(i).beu_int_source
158    if (!enableCHI) {
159      misc.peripheral_ports.get(i) := core_with_l2(i).tl_uncache
160    }
161    core_with_l2(i).memory_port.foreach(port => (misc.core_to_l3_ports.get)(i) :=* port)
162    memblock_pf_recv_nodes(i).map(recv => {
163      println(s"Connecting Core_${i}'s L1 pf source to L3!")
164      recv := core_with_l2(i).core_l3_pf_port.get
165    })
166    misc.debugModuleXbarOpt.foreach { debugModuleXbar =>
167      // SeperateTlBus can only be connected to DebugModule now in non-XSNoCTop environment
168      println(s"SeparateDM: ${SeperateDM}")
169      println(s"misc.debugModuleXbarOpt: ${misc.debugModuleXbarOpt}")
170      require(core_with_l2(i).sep_tl_opt.isDefined)
171      require(SeperateTLBusRanges.size == 1)
172      require(SeperateTLBusRanges.head == p(DebugModuleKey).get.address)
173      debugModuleXbar := core_with_l2(i).sep_tl_opt.get
174    }
175  }
176
177  l3cacheOpt.map(_.ctlnode.map(_ := misc.peripheralXbar.get))
178  l3cacheOpt.map(_.intnode.map(int => {
179    misc.plic.intnode := IntBuffer() := int
180  }))
181
182  val core_rst_nodes = if(l3cacheOpt.nonEmpty && l3cacheOpt.get.rst_nodes.nonEmpty){
183    l3cacheOpt.get.rst_nodes.get
184  } else {
185    core_with_l2.map(_ => BundleBridgeSource(() => Reset()))
186  }
187
188  core_rst_nodes.zip(core_with_l2.map(_.core_reset_sink)).foreach({
189    case (source, sink) =>  sink := source
190  })
191
192  l3cacheOpt match {
193    case Some(l3) =>
194      misc.l3_out :*= l3.node :*= misc.l3_banked_xbar.get
195      l3.pf_recv_node.map(recv => {
196        println("Connecting L1 prefetcher to L3!")
197        recv := l3_pf_sender_opt.get
198      })
199      l3.tpmeta_recv_node.foreach(recv => {
200        for ((core, i) <- core_with_l2.zipWithIndex) {
201          println(s"Connecting core_$i\'s L2 TPmeta request to L3!")
202          recv := core.core_l3_tpmeta_source_port.get
203        }
204      })
205      l3.tpmeta_send_node.foreach(send => {
206        val broadcast = LazyModule(new ValidIOBroadcast[TPmetaResp]())
207        broadcast.node := send
208        for ((core, i) <- core_with_l2.zipWithIndex) {
209          println(s"Connecting core_$i\'s L2 TPmeta response to L3!")
210          core.core_l3_tpmeta_sink_port.get := broadcast.node
211        }
212      })
213    case None =>
214  }
215
216  chi_llcBridge_opt match {
217    case Some(ncb) =>
218      misc.soc_xbar.get := ncb.axi4node
219    case None =>
220  }
221
222  chi_mmioBridge_opt.foreach { e =>
223    e match {
224      case Some(ncb) =>
225        misc.soc_xbar.get := ncb.axi4node
226      case None =>
227    }
228  }
229
230  class XSTopImp(wrapper: LazyModule) extends LazyRawModuleImp(wrapper) {
231    soc.XSTopPrefix.foreach { prefix =>
232      val mod = this.toNamed
233      annotate(new ChiselAnnotation {
234        def toFirrtl = NestedPrefixModulesAnnotation(mod, prefix, true)
235      })
236    }
237
238    FileRegisters.add("dts", dts)
239    FileRegisters.add("graphml", graphML)
240    FileRegisters.add("json", json)
241    FileRegisters.add("plusArgs", freechips.rocketchip.util.PlusArgArtefacts.serialize_cHeader())
242
243    val dma = socMisc.map(m => IO(Flipped(new VerilogAXI4Record(m.dma.elts.head.params))))
244    val peripheral = IO(new VerilogAXI4Record(misc.peripheral.elts.head.params))
245    val memory = IO(new VerilogAXI4Record(misc.memory.elts.head.params))
246
247    socMisc match {
248      case Some(m) =>
249        m.dma.elements.head._2 <> dma.get.viewAs[AXI4Bundle]
250        dontTouch(dma.get)
251      case None =>
252    }
253
254    memory.viewAs[AXI4Bundle] <> misc.memory.elements.head._2
255    peripheral.viewAs[AXI4Bundle] <> misc.peripheral.elements.head._2
256
257    val io = IO(new Bundle {
258      val clock = Input(Clock())
259      val reset = Input(AsyncReset())
260      val sram_config = Input(UInt(16.W))
261      val extIntrs = Input(UInt(NrExtIntr.W))
262      val pll0_lock = Input(Bool())
263      val pll0_ctrl = Output(Vec(6, UInt(32.W)))
264      val systemjtag = new Bundle {
265        val jtag = Flipped(new JTAGIO(hasTRSTn = false))
266        val reset = Input(AsyncReset()) // No reset allowed on top
267        val mfr_id = Input(UInt(11.W))
268        val part_number = Input(UInt(16.W))
269        val version = Input(UInt(4.W))
270      }
271      val debug_reset = Output(Bool())
272      val rtc_clock = Input(Bool())
273      val cacheable_check = new TLPMAIO()
274      val riscv_halt = Output(Vec(NumCores, Bool()))
275      val riscv_critical_error = Output(Vec(NumCores, Bool()))
276      val riscv_rst_vec = Input(Vec(NumCores, UInt(soc.PAddrBits.W)))
277      val traceCoreInterface = Vec(NumCores, new Bundle {
278        val fromEncoder = Input(new Bundle {
279          val enable = Bool()
280          val stall  = Bool()
281        })
282        val toEncoder   = Output(new Bundle {
283          val cause     = UInt(TraceCauseWidth.W)
284          val tval      = UInt(TraceTvalWidth.W)
285          val priv      = UInt(TracePrivWidth.W)
286          val iaddr     = UInt((TraceTraceGroupNum * TraceIaddrWidth).W)
287          val itype     = UInt((TraceTraceGroupNum * TraceItypeWidth).W)
288          val iretire   = UInt((TraceTraceGroupNum * TraceIretireWidthCompressed).W)
289          val ilastsize = UInt((TraceTraceGroupNum * TraceIlastsizeWidth).W)
290        })
291      })
292    })
293
294    val reset_sync = withClockAndReset(io.clock, io.reset) { ResetGen() }
295    val jtag_reset_sync = withClockAndReset(io.systemjtag.jtag.TCK, io.systemjtag.reset) { ResetGen() }
296    val chi_openllc_opt = Option.when(enableCHI)(
297      withClockAndReset(io.clock, io.reset) {
298        Module(new OpenLLC()(p.alter((site, here, up) => {
299          case OpenLLCParamKey => soc.OpenLLCParamsOpt.get.copy(
300            hartIds = tiles.map(_.HartId),
301            FPGAPlatform = debugOpts.FPGAPlatform
302          )
303        })))
304      }
305    )
306
307    // override LazyRawModuleImp's clock and reset
308    childClock := io.clock
309    childReset := reset_sync
310
311    // output
312    io.debug_reset := misc.module.debug_module_io.debugIO.ndreset
313
314    // input
315    dontTouch(io)
316    dontTouch(memory)
317    misc.module.ext_intrs := io.extIntrs
318    misc.module.rtc_clock := io.rtc_clock
319    misc.module.pll0_lock := io.pll0_lock
320    misc.module.cacheable_check <> io.cacheable_check
321
322    io.pll0_ctrl <> misc.module.pll0_ctrl
323
324    val msiInfo = WireInit(0.U.asTypeOf(ValidIO(UInt(soc.IMSICParams.MSI_INFO_WIDTH.W))))
325
326
327    for ((core, i) <- core_with_l2.zipWithIndex) {
328      core.module.io.hartId := i.U
329      core.module.io.msiInfo := msiInfo
330      core.module.io.clintTime := misc.module.clintTime
331      io.riscv_halt(i) := core.module.io.cpu_halt
332      io.riscv_critical_error(i) := core.module.io.cpu_crtical_error
333      // trace Interface
334      val traceInterface = core.module.io.traceCoreInterface
335      traceInterface.fromEncoder := io.traceCoreInterface(i).fromEncoder
336      io.traceCoreInterface(i).toEncoder.priv := traceInterface.toEncoder.priv
337      io.traceCoreInterface(i).toEncoder.cause := traceInterface.toEncoder.trap.cause
338      io.traceCoreInterface(i).toEncoder.tval := traceInterface.toEncoder.trap.tval
339      io.traceCoreInterface(i).toEncoder.iaddr := VecInit(traceInterface.toEncoder.groups.map(_.bits.iaddr)).asUInt
340      io.traceCoreInterface(i).toEncoder.itype := VecInit(traceInterface.toEncoder.groups.map(_.bits.itype)).asUInt
341      io.traceCoreInterface(i).toEncoder.iretire := VecInit(traceInterface.toEncoder.groups.map(_.bits.iretire)).asUInt
342      io.traceCoreInterface(i).toEncoder.ilastsize := VecInit(traceInterface.toEncoder.groups.map(_.bits.ilastsize)).asUInt
343
344      core.module.io.dft.foreach(dontTouch(_) := DontCare)
345      core.module.io.dft_reset.foreach(dontTouch(_) := DontCare)
346      core.module.io.reset_vector := io.riscv_rst_vec(i)
347    }
348
349    withClockAndReset(io.clock, io.reset) {
350      Option.when(enableCHI)(true.B).foreach { _ =>
351        for ((core, i) <- core_with_l2.zipWithIndex) {
352          val mmioLogger = CHILogger(s"L2[${i}]_MMIO", true)
353          val llcLogger = CHILogger(s"L2[${i}]_LLC", true)
354          dontTouch(core.module.io.chi.get)
355          bind(
356            route(
357              core.module.io.chi.get, Map((AddressSet(0x0L, 0x00007fffffffL), NumCores + i)) ++ AddressSet(0x0L,
358              0xffffffffffffL).subtract(AddressSet(0x0L, 0x00007fffffffL)).map(addr => (addr, NumCores * 2)).toMap
359            ),
360            Map((NumCores + i) -> mmioLogger.io.up, (NumCores * 2) -> llcLogger.io.up)
361          )
362          chi_mmioBridge_opt(i).get.module.io.chi.connect(mmioLogger.io.down)
363          chi_openllc_opt.get.io.rn(i) <> llcLogger.io.down
364          require(core.module.io.chi.get.getWidth == llcLogger.io.up.getWidth)
365          require(llcLogger.io.down.getWidth == chi_openllc_opt.get.io.rn(i).getWidth)
366        }
367        val memLogger = CHILogger(s"LLC_MEM", true)
368        chi_openllc_opt.get.io.sn.connect(memLogger.io.up)
369        chi_llcBridge_opt.get.module.io.chi.connect(memLogger.io.down)
370        chi_openllc_opt.get.io.nodeID := (NumCores * 2).U
371        chi_openllc_opt.foreach { l3 =>
372          l3.io.debugTopDown.robHeadPaddr := core_with_l2.map(_.module.io.debugTopDown.robHeadPaddr)
373        }
374        core_with_l2.zip(chi_openllc_opt.get.io.debugTopDown.addrMatch).foreach { case (tile, l3Match) =>
375          tile.module.io.debugTopDown.l3MissMatch := l3Match
376        }
377        core_with_l2.map(_.module.io.l3Miss := (if (chi_openllc_opt.nonEmpty) chi_openllc_opt.get.io.l3Miss else false.B))
378      }
379    }
380
381    if(l3cacheOpt.isEmpty || l3cacheOpt.get.rst_nodes.isEmpty){
382      // tie off core soft reset
383      for(node <- core_rst_nodes){
384        node.out.head._1 := false.B.asAsyncReset
385      }
386    }
387
388    l3cacheOpt match {
389      case Some(l3) =>
390        l3.pf_recv_node match {
391          case Some(recv) =>
392            l3_pf_sender_opt.get.out.head._1.addr_valid := VecInit(memblock_pf_recv_nodes.map(_.get.in.head._1.addr_valid)).asUInt.orR
393            for (i <- 0 until NumCores) {
394              when(memblock_pf_recv_nodes(i).get.in.head._1.addr_valid) {
395                l3_pf_sender_opt.get.out.head._1.addr := memblock_pf_recv_nodes(i).get.in.head._1.addr
396                l3_pf_sender_opt.get.out.head._1.l2_pf_en := memblock_pf_recv_nodes(i).get.in.head._1.l2_pf_en
397              }
398            }
399          case None =>
400        }
401        l3.module.io.debugTopDown.robHeadPaddr := core_with_l2.map(_.module.io.debugTopDown.robHeadPaddr)
402        core_with_l2.zip(l3.module.io.debugTopDown.addrMatch).foreach { case (tile, l3Match) => tile.module.io.debugTopDown.l3MissMatch := l3Match }
403        core_with_l2.foreach(_.module.io.l3Miss := l3.module.io.l3Miss)
404      case None =>
405    }
406
407    (chi_openllc_opt, l3cacheOpt) match {
408      case (None, None) =>
409        core_with_l2.foreach(_.module.io.debugTopDown.l3MissMatch := false.B)
410        core_with_l2.foreach(_.module.io.l3Miss := false.B)
411      case _ =>
412    }
413
414    core_with_l2.zipWithIndex.foreach { case (tile, i) =>
415      tile.module.io.nodeID.foreach { case nodeID =>
416        nodeID := i.U
417        dontTouch(nodeID)
418      }
419    }
420
421    misc.module.debug_module_io.resetCtrl.hartIsInReset := core_with_l2.map(_.module.io.hartIsInReset)
422    misc.module.debug_module_io.clock := io.clock
423    misc.module.debug_module_io.reset := reset_sync
424
425    misc.module.debug_module_io.debugIO.reset := misc.module.reset
426    misc.module.debug_module_io.debugIO.clock := io.clock
427    // TODO: delay 3 cycles?
428    misc.module.debug_module_io.debugIO.dmactiveAck := misc.module.debug_module_io.debugIO.dmactive
429    // jtag connector
430    misc.module.debug_module_io.debugIO.systemjtag.foreach { x =>
431      x.jtag        <> io.systemjtag.jtag
432      x.reset       := jtag_reset_sync
433      x.mfr_id      := io.systemjtag.mfr_id
434      x.part_number := io.systemjtag.part_number
435      x.version     := io.systemjtag.version
436    }
437
438    withClockAndReset(io.clock, reset_sync) {
439      // Modules are reset one by one
440      // reset ----> SYNC --> {SoCMisc, L3 Cache, Cores}
441      val resetChain = Seq(Seq(misc.module) ++ l3cacheOpt.map(_.module))
442      ResetGen(resetChain, reset_sync, !debugOpts.ResetGen)
443      // Ensure that cores could be reset when DM disable `hartReset` or l3cacheOpt.isEmpty.
444      val dmResetReqVec = misc.module.debug_module_io.resetCtrl.hartResetReq.getOrElse(0.U.asTypeOf(Vec(core_with_l2.map(_.module).length, Bool())))
445      val syncResetCores = if(l3cacheOpt.nonEmpty) l3cacheOpt.map(_.module).get.reset.asBool else misc.module.reset.asBool
446      (core_with_l2.map(_.module)).zip(dmResetReqVec).map { case(core, dmResetReq) =>
447        ResetGen(Seq(Seq(core)), (syncResetCores || dmResetReq).asAsyncReset, !debugOpts.ResetGen)
448      }
449    }
450
451  }
452
453  lazy val module = new XSTopImp(this)
454}
455
456class XSTileDiffTop(implicit p: Parameters) extends Module {
457  override val desiredName: String = "XSDiffTop"
458  val l_soc = LazyModule(new XSTop())
459  val soc = Module(l_soc.module)
460
461  // Expose XSTop IOs outside, i.e. io
462  def exposeIO(data: Data, name: String): Unit = {
463    val dummy = IO(chiselTypeOf(data)).suggestName(name)
464    dummy <> data
465  }
466  def exposeOptionIO(data: Option[Data], name: String): Unit = {
467    if (data.isDefined) {
468      val dummy = IO(chiselTypeOf(data.get)).suggestName(name)
469      dummy <> data.get
470    }
471  }
472  exposeIO(l_soc.nmi,"nmi")
473  exposeIO(soc.memory, "memory")
474  exposeIO(soc.peripheral,"peripheral")
475  exposeIO(soc.io,"io")
476  exposeOptionIO(soc.dma, "dma")
477
478  DifftestWiring.createAndConnectExtraIOs()
479  Profile.generateJson("XiangShan")
480}
481
482object TopMain extends App {
483  val (config, firrtlOpts, firtoolOpts) = ArgParser.parse(args)
484
485  // tools: init to close dpi-c when in fpga
486  val envInFPGA = config(DebugOptionsKey).FPGAPlatform
487  val enableDifftest = config(DebugOptionsKey).EnableDifftest || config(DebugOptionsKey).AlwaysBasicDiff
488  val enableChiselDB = config(DebugOptionsKey).EnableChiselDB
489  val enableConstantin = config(DebugOptionsKey).EnableConstantin
490  Constantin.init(enableConstantin && !envInFPGA)
491  ChiselDB.init(enableChiselDB && !envInFPGA)
492
493  if (config(SoCParamsKey).UseXSNoCDiffTop) {
494    Generator.execute(firrtlOpts, DisableMonitors(p => new XSNoCDiffTop()(p))(config), firtoolOpts)
495  } else if (config(SoCParamsKey).UseXSTileDiffTop) {
496    Generator.execute(firrtlOpts, DisableMonitors(p => new XSTileDiffTop()(p))(config), firtoolOpts)
497  } else {
498    val soc = if (config(SoCParamsKey).UseXSNoCTop)
499      DisableMonitors(p => LazyModule(new XSNoCTop()(p)))(config)
500    else
501      DisableMonitors(p => LazyModule(new XSTop()(p)))(config)
502
503    Generator.execute(firrtlOpts, soc.module, firtoolOpts)
504
505    // generate difftest bundles (w/o DifftestTopIO)
506    if (enableDifftest) {
507      DifftestModule.finish("XiangShan", false)
508    }
509  }
510
511  FileRegisters.write(fileDir = "./build", filePrefix = "XSTop.")
512}
513