xref: /XiangShan/src/main/scala/top/Top.scala (revision 9d5a20273d0b3574b169e80262a817d5cfdfd814)
18b037849SYinan Xupackage top
28b037849SYinan Xu
38b037849SYinan Xuimport chisel3._
48b037849SYinan Xuimport chisel3.util._
58b037849SYinan Xuimport xiangshan._
694c92d92SYinan Xuimport utils._
78b037849SYinan Xuimport system._
88b037849SYinan Xuimport chisel3.stage.ChiselGeneratorAnnotation
92225d46eSJiawei Linimport chipsalliance.rocketchip.config._
102e3a956eSLinJiaweiimport device.{AXI4Plic, TLTimer}
118b037849SYinan Xuimport freechips.rocketchip.diplomacy._
128b037849SYinan Xuimport freechips.rocketchip.tilelink._
138b037849SYinan Xuimport freechips.rocketchip.amba.axi4._
148b037849SYinan Xuimport freechips.rocketchip.devices.tilelink.{DevNullParams, TLError}
152e3a956eSLinJiaweiimport freechips.rocketchip.diplomaticobjectmodel.logicaltree.GenericLogicalTreeNode
162e3a956eSLinJiaweiimport freechips.rocketchip.interrupts.{IntSinkNode, IntSinkPortSimple}
172e3a956eSLinJiaweiimport freechips.rocketchip.tile.{BusErrorUnit, BusErrorUnitParams, XLen}
1894c92d92SYinan Xuimport sifive.blocks.inclusivecache.{InclusiveCache, InclusiveCacheMicroParameters, CacheParameters}
198b037849SYinan Xuimport xiangshan.cache.prefetch.L2Prefetcher
208b037849SYinan Xu
218b037849SYinan Xu
222225d46eSJiawei Linclass XSCoreWithL2()(implicit p: Parameters) extends LazyModule
232225d46eSJiawei Lin  with HasXSParameter with HasSoCParameter {
2494c92d92SYinan Xu  private val core = LazyModule(new XSCore())
2594c92d92SYinan Xu  private val l2prefetcher = LazyModule(new L2Prefetcher())
2694c92d92SYinan Xu  private val l2xbar = TLXbar()
27*9d5a2027SYinan Xu  private val l2cache = if (useFakeL2Cache) null else LazyModule(new InclusiveCache(
286c4d7a40SYinan Xu    CacheParameters(
296c4d7a40SYinan Xu      level = 2,
306c4d7a40SYinan Xu      ways = L2NWays,
316c4d7a40SYinan Xu      sets = L2NSets,
326c4d7a40SYinan Xu      blockBytes = L2BlockSize,
336c4d7a40SYinan Xu      beatBytes = L1BusWidth / 8, // beatBytes = l1BusDataWidth / 8
3411b3c588SAllen      cacheName = s"L2",
3583cb791fSallen      uncachedGet = true,
3611b3c588SAllen      enablePerf = false
376c4d7a40SYinan Xu    ),
386c4d7a40SYinan Xu    InclusiveCacheMicroParameters(
39f5089e26SWonicon      memCycles = 25,
406c4d7a40SYinan Xu      writeBytes = 32
412791c549Szfw    ),
422225d46eSJiawei Lin    fpga = debugOpts.FPGAPlatform
436c4d7a40SYinan Xu  ))
44*9d5a2027SYinan Xu
45*9d5a2027SYinan Xu  val memory_port = TLIdentityNode()
4694c92d92SYinan Xu  val uncache = TLXbar()
476c4d7a40SYinan Xu
48*9d5a2027SYinan Xu  if (!useFakeDCache) {
496c4d7a40SYinan Xu    l2xbar := TLBuffer() := core.memBlock.dcache.clientNode
50*9d5a2027SYinan Xu  }
51*9d5a2027SYinan Xu  if (!useFakeL1plusCache) {
526c4d7a40SYinan Xu    l2xbar := TLBuffer() := core.l1pluscache.clientNode
53*9d5a2027SYinan Xu  }
54*9d5a2027SYinan Xu  if (!useFakePTW) {
556c4d7a40SYinan Xu    l2xbar := TLBuffer() := core.ptw.node
56*9d5a2027SYinan Xu  }
576c4d7a40SYinan Xu  l2xbar := TLBuffer() := l2prefetcher.clientNode
58*9d5a2027SYinan Xu  if (useFakeL2Cache) {
59*9d5a2027SYinan Xu    memory_port := l2xbar
60*9d5a2027SYinan Xu  }
61*9d5a2027SYinan Xu  else {
626c4d7a40SYinan Xu    l2cache.node := TLBuffer() := l2xbar
63*9d5a2027SYinan Xu    memory_port := l2cache.node
64*9d5a2027SYinan Xu  }
656c4d7a40SYinan Xu
6694c92d92SYinan Xu  uncache := TLBuffer() := core.frontend.instrUncache.clientNode
6794c92d92SYinan Xu  uncache := TLBuffer() := core.memBlock.uncache.clientNode
686c4d7a40SYinan Xu
6994c92d92SYinan Xu  lazy val module = new LazyModuleImp(this) {
706c4d7a40SYinan Xu    val io = IO(new Bundle {
716c4d7a40SYinan Xu      val hartId = Input(UInt(64.W))
726c4d7a40SYinan Xu      val externalInterrupt = new ExternalInterruptIO
734e3ce935Sljw      val l1plus_error, icache_error, dcache_error = new L1CacheErrorInfo
746c4d7a40SYinan Xu    })
756c4d7a40SYinan Xu
7694c92d92SYinan Xu    core.module.io.hartId := io.hartId
7794c92d92SYinan Xu    core.module.io.externalInterrupt := io.externalInterrupt
78c0bc1ee4SYinan Xu    l2prefetcher.module.io.enable := core.module.io.l2_pf_enable
79*9d5a2027SYinan Xu    if (useFakeL2Cache) {
80*9d5a2027SYinan Xu      l2prefetcher.module.io.in := DontCare
81*9d5a2027SYinan Xu    }
82*9d5a2027SYinan Xu    else {
8394c92d92SYinan Xu      l2prefetcher.module.io.in <> l2cache.module.io
84*9d5a2027SYinan Xu    }
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))
9394c92d92SYinan Xu    l2prefetcher.module.reset := l2_reset_gen.io.out
94*9d5a2027SYinan Xu    if (!useFakeL2Cache) {
9594c92d92SYinan Xu      l2cache.module.reset := l2_reset_gen.io.out
9694c92d92SYinan Xu    }
9794c92d92SYinan Xu  }
98*9d5a2027SYinan Xu}
996c4d7a40SYinan Xu
1002225d46eSJiawei Linabstract class BaseXSSoc()(implicit p: Parameters) extends LazyModule with HasSoCParameter {
1018b037849SYinan Xu  val bankedNode = BankBinder(L3NBanks, L3BlockSize)
1028b037849SYinan Xu  val peripheralXbar = TLXbar()
1038b037849SYinan Xu  val l3_xbar = TLXbar()
1048b037849SYinan Xu}
1058b037849SYinan Xu
1068b037849SYinan Xu// We adapt the following three traits from rocket-chip.
1078b037849SYinan Xu// Source: rocket-chip/src/main/scala/subsystem/Ports.scala
1088b037849SYinan Xutrait HaveSlaveAXI4Port {
1098b037849SYinan Xu  this: BaseXSSoc =>
1108b037849SYinan Xu
1118b037849SYinan Xu  val idBits = 16
1128b037849SYinan Xu
1138b037849SYinan Xu  val l3FrontendAXI4Node = AXI4MasterNode(Seq(AXI4MasterPortParameters(
1148b037849SYinan Xu    Seq(AXI4MasterParameters(
1158b037849SYinan Xu      name = "dma",
1168b037849SYinan Xu      id = IdRange(0, 1 << idBits)
1178b037849SYinan Xu    ))
1188b037849SYinan Xu  )))
1198b037849SYinan Xu  private val errorDevice = LazyModule(new TLError(
1208b037849SYinan Xu    params = DevNullParams(
1218b037849SYinan Xu      address = Seq(AddressSet(0x0, 0x7fffffffL)),
1228b037849SYinan Xu      maxAtomic = 8,
1238b037849SYinan Xu      maxTransfer = 64),
1242225d46eSJiawei Lin    beatBytes = L3InnerBusWidth / 8
1258b037849SYinan Xu  ))
1268b037849SYinan Xu  private val error_xbar = TLXbar()
1278b037849SYinan Xu
1288b037849SYinan Xu  error_xbar :=
1298b037849SYinan Xu    AXI4ToTL() :=
1308b037849SYinan Xu    AXI4UserYanker(Some(1)) :=
1318b037849SYinan Xu    AXI4Fragmenter() :=
1328b037849SYinan Xu    AXI4IdIndexer(1) :=
1338b037849SYinan Xu    l3FrontendAXI4Node
1348b037849SYinan Xu  errorDevice.node := error_xbar
1358b037849SYinan Xu  l3_xbar :=
1368b037849SYinan Xu    TLBuffer() :=
1378b037849SYinan Xu    error_xbar
1388b037849SYinan Xu
1398b037849SYinan Xu  val dma = InModuleBody {
1408b037849SYinan Xu    l3FrontendAXI4Node.makeIOs()
1418b037849SYinan Xu  }
1428b037849SYinan Xu}
1438b037849SYinan Xu
1448b037849SYinan Xutrait HaveAXI4MemPort {
1458b037849SYinan Xu  this: BaseXSSoc =>
1468b037849SYinan Xu  // 40-bit physical address
1478b037849SYinan Xu  val memRange = AddressSet(0x00000000L, 0xffffffffffL).subtract(AddressSet(0x0L, 0x7fffffffL))
148329e267dSYinan Xu  val memAXI4SlaveNode = AXI4SlaveNode(Seq(
1498b037849SYinan Xu    AXI4SlavePortParameters(
1508b037849SYinan Xu      slaves = Seq(
1518b037849SYinan Xu        AXI4SlaveParameters(
1528b037849SYinan Xu          address = memRange,
1538b037849SYinan Xu          regionType = RegionType.UNCACHED,
1548b037849SYinan Xu          executable = true,
1558b037849SYinan Xu          supportsRead = TransferSizes(1, L3BlockSize),
1568b037849SYinan Xu          supportsWrite = TransferSizes(1, L3BlockSize),
1578b037849SYinan Xu          interleavedId = Some(0)
1588b037849SYinan Xu        )
1598b037849SYinan Xu      ),
1602225d46eSJiawei Lin      beatBytes = L3OuterBusWidth / 8
1618b037849SYinan Xu    )
162329e267dSYinan Xu  ))
1638b037849SYinan Xu
164329e267dSYinan Xu  val mem_xbar = TLXbar()
165329e267dSYinan Xu  mem_xbar :=* TLBuffer() :=* TLCacheCork() :=* bankedNode
166329e267dSYinan Xu  memAXI4SlaveNode :=
167329e267dSYinan Xu    AXI4UserYanker() :=
168329e267dSYinan Xu    AXI4Deinterleaver(L3BlockSize) :=
169329e267dSYinan Xu    TLToAXI4() :=
1702225d46eSJiawei Lin    TLWidthWidget(L3OuterBusWidth / 8) :=
171329e267dSYinan Xu    mem_xbar
1728b037849SYinan Xu
1738b037849SYinan Xu  val memory = InModuleBody {
1748b037849SYinan Xu    memAXI4SlaveNode.makeIOs()
1758b037849SYinan Xu  }
1768b037849SYinan Xu}
1778b037849SYinan Xu
1788b037849SYinan Xu
1798b037849SYinan Xutrait HaveAXI4PeripheralPort { this: BaseXSSoc =>
1808b037849SYinan Xu  // on-chip devices: 0x3800_000 - 0x3fff_ffff
1818b037849SYinan Xu  val onChipPeripheralRange = AddressSet(0x38000000L, 0x07ffffffL)
1828b037849SYinan Xu  val peripheralRange = AddressSet(0x0, 0x7fffffff).subtract(onChipPeripheralRange)
1838b037849SYinan Xu  val peripheralNode = AXI4SlaveNode(Seq(AXI4SlavePortParameters(
1848b037849SYinan Xu    Seq(AXI4SlaveParameters(
1858b037849SYinan Xu      address = peripheralRange,
1868b037849SYinan Xu      regionType = RegionType.UNCACHED,
1878b037849SYinan Xu      supportsRead = TransferSizes(1, 8),
1888b037849SYinan Xu      supportsWrite = TransferSizes(1, 8),
1898b037849SYinan Xu      interleavedId = Some(0)
1908b037849SYinan Xu    )),
1918b037849SYinan Xu    beatBytes = 8
1928b037849SYinan Xu  )))
1938b037849SYinan Xu
1948b037849SYinan Xu  peripheralNode :=
1958b037849SYinan Xu    AXI4UserYanker() :=
1969d4d50e0SYinan Xu    AXI4Deinterleaver(8) :=
1978b037849SYinan Xu    TLToAXI4() :=
1988b037849SYinan Xu    peripheralXbar
1998b037849SYinan Xu
2008b037849SYinan Xu  val peripheral = InModuleBody {
2018b037849SYinan Xu    peripheralNode.makeIOs()
2028b037849SYinan Xu  }
2038b037849SYinan Xu
2048b037849SYinan Xu}
2058b037849SYinan Xu
2062225d46eSJiawei Linclass XSTop()(implicit p: Parameters) extends XSTopWithoutDMA
2072225d46eSJiawei Lin  with HaveSlaveAXI4Port
2088b037849SYinan Xu
2092225d46eSJiawei Linclass XSTopWithoutDMA()(implicit p: Parameters) extends BaseXSSoc()
2108b037849SYinan Xu  with HaveAXI4MemPort
2118b037849SYinan Xu  with HaveAXI4PeripheralPort
2128b037849SYinan Xu{
2138b037849SYinan Xu
2142225d46eSJiawei Lin  println(s"FPGASoC cores: $NumCores banks: $L3NBanks block size: $L3BlockSize bus size: $L3OuterBusWidth")
2158b037849SYinan Xu
2162225d46eSJiawei Lin  val core_with_l2 = soc.cores.map(coreParams =>
2172225d46eSJiawei Lin    LazyModule(new XSCoreWithL2()(p.alterPartial({
2182225d46eSJiawei Lin      case XSCoreParamsKey => coreParams
2192225d46eSJiawei Lin    })))
2202225d46eSJiawei Lin  )
2218b037849SYinan Xu
2228b037849SYinan Xu  for (i <- 0 until NumCores) {
22394c92d92SYinan Xu    peripheralXbar := TLBuffer() := core_with_l2(i).uncache
224*9d5a2027SYinan Xu    l3_xbar := TLBuffer() := core_with_l2(i).memory_port
2258b037849SYinan Xu  }
2268b037849SYinan Xu
2278b037849SYinan Xu  private val clint = LazyModule(new TLTimer(
2288b037849SYinan Xu    Seq(AddressSet(0x38000000L, 0x0000ffffL)),
2292225d46eSJiawei Lin    sim = !debugOpts.FPGAPlatform, NumCores
2308b037849SYinan Xu  ))
2318b037849SYinan Xu  clint.node := peripheralXbar
2328b037849SYinan Xu
2332e3a956eSLinJiawei  val fakeTreeNode = new GenericLogicalTreeNode
2342e3a956eSLinJiawei  val beu = LazyModule(
2352e3a956eSLinJiawei    new BusErrorUnit(new XSL1BusErrors(NumCores), BusErrorUnitParams(0x38010000), fakeTreeNode))
2362e3a956eSLinJiawei  beu.node := peripheralXbar
2372e3a956eSLinJiawei
2382225d46eSJiawei Lin  class BeuSinkNode()(implicit p: Parameters) extends LazyModule {
2392e3a956eSLinJiawei    val intSinkNode = IntSinkNode(IntSinkPortSimple())
2402e3a956eSLinJiawei    lazy val module = new LazyModuleImp(this){
2412e3a956eSLinJiawei      val interrupt = IO(Output(Bool()))
2422e3a956eSLinJiawei      interrupt := intSinkNode.in.head._1.head
2432e3a956eSLinJiawei    }
2442e3a956eSLinJiawei  }
2452e3a956eSLinJiawei  val beuSink = LazyModule(new BeuSinkNode())
2462e3a956eSLinJiawei  beuSink.intSinkNode := beu.intNode
2472e3a956eSLinJiawei
2488b037849SYinan Xu  val plic = LazyModule(new AXI4Plic(
2498b037849SYinan Xu    Seq(AddressSet(0x3c000000L, 0x03ffffffL)),
2502225d46eSJiawei Lin    NumCores, NrExtIntr + 1,
2512225d46eSJiawei Lin    !debugOpts.FPGAPlatform,
2528b037849SYinan Xu  ))
2538b037849SYinan Xu  plic.node := AXI4IdentityNode() := AXI4UserYanker() := TLToAXI4() := peripheralXbar
2548b037849SYinan Xu
255*9d5a2027SYinan Xu  val l3cache = if (useFakeL3Cache) null else LazyModule(new InclusiveCache(
2568b037849SYinan Xu    CacheParameters(
2578b037849SYinan Xu      level = 3,
2588b037849SYinan Xu      ways = L3NWays,
2598b037849SYinan Xu      sets = L3NSets,
2608b037849SYinan Xu      blockBytes = L3BlockSize,
2612225d46eSJiawei Lin      beatBytes = L3InnerBusWidth / 8,
26211b3c588SAllen      cacheName = "L3",
26383cb791fSallen      uncachedGet = false,
26411b3c588SAllen      enablePerf = false
2658b037849SYinan Xu    ),
2668b037849SYinan Xu    InclusiveCacheMicroParameters(
267f5089e26SWonicon      memCycles = 25,
2688b037849SYinan Xu      writeBytes = 32
2692791c549Szfw    ),
2702225d46eSJiawei Lin    fpga = debugOpts.FPGAPlatform
27194c92d92SYinan Xu  ))
272*9d5a2027SYinan Xu  val l3Ignore = if (useFakeL3Cache) TLIgnoreNode() else null
2738b037849SYinan Xu
274*9d5a2027SYinan Xu  if (useFakeL3Cache) {
275*9d5a2027SYinan Xu    bankedNode :*= l3Ignore :*= l3_xbar
276*9d5a2027SYinan Xu  }
277*9d5a2027SYinan Xu  else {
27894c92d92SYinan Xu    bankedNode :*= l3cache.node :*= TLBuffer() :*= l3_xbar
279*9d5a2027SYinan Xu  }
2808b037849SYinan Xu
28194c92d92SYinan Xu  lazy val module = new LazyRawModuleImp(this) {
2828b037849SYinan Xu    val io = IO(new Bundle {
28394c92d92SYinan Xu      val clock = Input(Bool())
28494c92d92SYinan Xu      val reset = Input(Bool())
2858b037849SYinan Xu      val extIntrs = Input(UInt(NrExtIntr.W))
2868b037849SYinan Xu      // val meip = Input(Vec(NumCores, Bool()))
2872225d46eSJiawei Lin      val ila = if(debugOpts.FPGAPlatform && EnableILA) Some(Output(new ILABundle)) else None
2888b037849SYinan Xu    })
28994c92d92SYinan Xu    childClock := io.clock.asClock()
2908b037849SYinan Xu
29194c92d92SYinan Xu    withClockAndReset(childClock, io.reset) {
2922225d46eSJiawei Lin      val resetGen = Module(new ResetGen(1, !debugOpts.FPGAPlatform))
29394c92d92SYinan Xu      resetGen.suggestName("top_reset_gen")
29494c92d92SYinan Xu      childReset := resetGen.io.out
29594c92d92SYinan Xu    }
29694c92d92SYinan Xu
29794c92d92SYinan Xu    withClockAndReset(childClock, childReset) {
298c0bc1ee4SYinan Xu      plic.module.io.extra.get.intrVec <> Cat(beuSink.module.interrupt, io.extIntrs)
299c0bc1ee4SYinan Xu
3008b037849SYinan Xu      for (i <- 0 until NumCores) {
3012225d46eSJiawei Lin        val core_reset_gen = Module(new ResetGen(1, !debugOpts.FPGAPlatform))
30294c92d92SYinan Xu        core_reset_gen.suggestName(s"core_${i}_reset_gen")
30394c92d92SYinan Xu        core_with_l2(i).module.reset := core_reset_gen.io.out
3046c4d7a40SYinan Xu        core_with_l2(i).module.io.hartId := i.U
3056c4d7a40SYinan Xu        core_with_l2(i).module.io.externalInterrupt.mtip := clint.module.io.mtip(i)
3066c4d7a40SYinan Xu        core_with_l2(i).module.io.externalInterrupt.msip := clint.module.io.msip(i)
3076c4d7a40SYinan Xu        core_with_l2(i).module.io.externalInterrupt.meip := plic.module.io.extra.get.meip(i)
308c0bc1ee4SYinan Xu        beu.module.io.errors.l1plus(i) := core_with_l2(i).module.io.l1plus_error
309c0bc1ee4SYinan Xu        beu.module.io.errors.icache(i) := core_with_l2(i).module.io.icache_error
310c0bc1ee4SYinan Xu        beu.module.io.errors.dcache(i) := core_with_l2(i).module.io.dcache_error
3118b037849SYinan Xu      }
3128b037849SYinan Xu
313*9d5a2027SYinan Xu      if (!useFakeL3Cache) {
3142225d46eSJiawei Lin        val l3_reset_gen = Module(new ResetGen(1, !debugOpts.FPGAPlatform))
31594c92d92SYinan Xu        l3_reset_gen.suggestName("l3_reset_gen")
31694c92d92SYinan Xu        l3cache.module.reset := l3_reset_gen.io.out
31794c92d92SYinan Xu      }
3188b037849SYinan Xu    }
3198b037849SYinan Xu  }
320*9d5a2027SYinan Xu}
3218b037849SYinan Xu
3222225d46eSJiawei Linclass DefaultConfig(n: Int) extends Config((site, here, up) => {
3232225d46eSJiawei Lin  case XLen => 64
3242225d46eSJiawei Lin  case DebugOptionsKey => DebugOptions()
3252225d46eSJiawei Lin  case SoCParamsKey => SoCParameters(
3262225d46eSJiawei Lin    cores = List.tabulate(n){ i => XSCoreParameters(HartId = i) }
3272225d46eSJiawei Lin  )
3282225d46eSJiawei Lin})
3292225d46eSJiawei Lin
3308b037849SYinan Xuobject TopMain extends App {
3318b037849SYinan Xu  override def main(args: Array[String]): Unit = {
3322225d46eSJiawei Lin    val numCores = if(args.contains("--dual-core")) 2 else 1
3338b037849SYinan Xu    val otherArgs = args.filterNot(_ == "--dual-core")
3342225d46eSJiawei Lin    implicit val config = new DefaultConfig(numCores)
3358b037849SYinan Xu    XiangShanStage.execute(otherArgs, Seq(
3368b037849SYinan Xu      ChiselGeneratorAnnotation(() => {
3378b037849SYinan Xu        val soc = LazyModule(new XSTop())
3388b037849SYinan Xu        soc.module
3398b037849SYinan Xu      })
3408b037849SYinan Xu    ))
3418b037849SYinan Xu  }
3428b037849SYinan Xu}
343