xref: /XiangShan/src/main/scala/system/SoC.scala (revision 4e3ce9354dd67209809b1ad1d063e3a486c358e7)
1006e1884SZihao Yupackage system
2006e1884SZihao Yu
33e586e47Slinjiaweiimport chipsalliance.rocketchip.config.Parameters
40584d3a8SLinJiaweiimport device.{AXI4Plic, AXI4Timer, TLTimer}
5006e1884SZihao Yuimport chisel3._
6096ea47eSzhanglinjuanimport chisel3.util._
73e586e47Slinjiaweiimport freechips.rocketchip.diplomacy.{AddressSet, LazyModule, LazyModuleImp}
897eae8a0SWang Huizheimport freechips.rocketchip.tilelink.{BankBinder, TLBuffer, TLBundleParameters, TLCacheCork, TLClientNode, TLFilter, TLFuzzer, TLIdentityNode, TLToAXI4, TLWidthWidget, TLXbar}
90584d3a8SLinJiaweiimport utils.{DataDontCareNode, DebugIdentityNode}
10737d2306SWang Huizheimport utils.XSInfo
110584d3a8SLinJiaweiimport xiangshan.{DifftestBundle, HasXSLog, HasXSParameter, XSBundle, XSCore}
1287b0fcb0Szhanglinjuanimport xiangshan.cache.prefetch._
136e91cacaSYinan Xuimport sifive.blocks.inclusivecache.{CacheParameters, InclusiveCache, InclusiveCacheMicroParameters}
1497eae8a0SWang Huizheimport freechips.rocketchip.diplomacy.{AddressSet, LazyModule, LazyModuleImp}
1597eae8a0SWang Huizheimport freechips.rocketchip.devices.tilelink.{DevNullParams, TLError}
1697eae8a0SWang Huizheimport freechips.rocketchip.amba.axi4.{AXI4Deinterleaver, AXI4Fragmenter, AXI4IdIndexer, AXI4IdentityNode, AXI4ToTL, AXI4UserYanker}
170584d3a8SLinJiaweiimport freechips.rocketchip.diplomaticobjectmodel.logicaltree.GenericLogicalTreeNode
180584d3a8SLinJiaweiimport freechips.rocketchip.interrupts.{IntSinkNode, IntSinkParameters, IntSinkPortParameters, IntSinkPortSimple}
190584d3a8SLinJiaweiimport freechips.rocketchip.tile.{BusErrorUnit, BusErrorUnitParams, BusErrors, L1BusErrors}
20a428082bSLinJiawei
21a428082bSLinJiaweicase class SoCParameters
22a428082bSLinJiawei(
23f874f036SYinan Xu  NumCores: Integer = 1,
24a428082bSLinJiawei  EnableILA: Boolean = false,
25a428082bSLinJiawei  HasL2Cache: Boolean = false,
26a428082bSLinJiawei  HasPrefetch: Boolean = false
27a428082bSLinJiawei)
28006e1884SZihao Yu
297d5ddbe6SLinJiaweitrait HasSoCParameter extends HasXSParameter{
303e586e47Slinjiawei  val soc = top.Parameters.get.socParameters
31f874f036SYinan Xu  val NumCores = soc.NumCores
32a428082bSLinJiawei  val EnableILA = soc.EnableILA
33a428082bSLinJiawei  val HasL2cache = soc.HasL2Cache
34a428082bSLinJiawei  val HasPrefetch = soc.HasPrefetch
35303b861dSZihao Yu}
36303b861dSZihao Yu
371e3fad10SLinJiaweiclass ILABundle extends Bundle {}
38303b861dSZihao Yu
393e586e47Slinjiawei
400584d3a8SLinJiaweiclass L1CacheErrorInfo extends XSBundle{
410584d3a8SLinJiawei  val paddr = Valid(UInt(PAddrBits.W))
420584d3a8SLinJiawei  // for now, we only detect ecc
430584d3a8SLinJiawei  val ecc_error = Valid(Bool())
443e586e47Slinjiawei}
453e586e47Slinjiawei
469637c0c6SLinJiaweiclass XSL1BusErrors(val nCores: Int) extends  BusErrors {
479637c0c6SLinJiawei  val icache = Vec(nCores, new L1CacheErrorInfo)
48*4e3ce935Sljw  val l1plus = Vec(nCores, new L1CacheErrorInfo)
499637c0c6SLinJiawei  val dcache = Vec(nCores, new L1CacheErrorInfo)
509637c0c6SLinJiawei
519637c0c6SLinJiawei  override def toErrorList: List[Option[(ValidIO[UInt], String, String)]] =
529637c0c6SLinJiawei    List.tabulate(nCores){i =>
539637c0c6SLinJiawei      List(
549637c0c6SLinJiawei        Some(icache(i).paddr, s"IBUS_$i", s"Icache_$i bus error"),
559637c0c6SLinJiawei        Some(icache(i).ecc_error, s"I_ECC_$i", s"Icache_$i ecc error"),
56*4e3ce935Sljw        Some(l1plus(i).paddr, s"L1PLUS_$i", s"L1PLUS_$i bus error"),
57*4e3ce935Sljw        Some(l1plus(i).ecc_error, s"L1PLUS_ECC_$i", s"L1PLUS_$i ecc error"),
589637c0c6SLinJiawei        Some(dcache(i).paddr, s"DBUS_$i", s"Dcache_$i bus error"),
599637c0c6SLinJiawei        Some(dcache(i).ecc_error, s"D_ECC_$i", s"Dcache_$i ecc error")
600584d3a8SLinJiawei      )
619637c0c6SLinJiawei    }.flatten
620584d3a8SLinJiawei}
633e586e47Slinjiawei
643e586e47Slinjiaweiclass XSSoc()(implicit p: Parameters) extends LazyModule with HasSoCParameter {
655d65f258SYinan Xu  // CPU Cores
665d65f258SYinan Xu  private val xs_core = Seq.fill(NumCores)(LazyModule(new XSCore()))
673e586e47Slinjiawei
685d65f258SYinan Xu  // L1 to L2 network
695d65f258SYinan Xu  // -------------------------------------------------
705d65f258SYinan Xu  private val l2_xbar = Seq.fill(NumCores)(TLXbar())
715d65f258SYinan Xu
725d65f258SYinan Xu  private val l2cache = Seq.fill(NumCores)(LazyModule(new InclusiveCache(
735d65f258SYinan Xu    CacheParameters(
745d65f258SYinan Xu      level = 2,
755d65f258SYinan Xu      ways = L2NWays,
765d65f258SYinan Xu      sets = L2NSets,
775d65f258SYinan Xu      blockBytes = L2BlockSize,
785d65f258SYinan Xu      beatBytes = L1BusWidth / 8, // beatBytes = l1BusDataWidth / 8
795d65f258SYinan Xu      cacheName = s"L2"
805d65f258SYinan Xu    ),
815d65f258SYinan Xu    InclusiveCacheMicroParameters(
828d9f4ff7SAllen      writeBytes = 32
835d65f258SYinan Xu    )
845d65f258SYinan Xu  )))
853e586e47Slinjiawei
8687b0fcb0Szhanglinjuan  private val l2prefetcher = Seq.fill(NumCores)(LazyModule(new L2Prefetcher()))
8787b0fcb0Szhanglinjuan
886e91cacaSYinan Xu  // L2 to L3 network
896e91cacaSYinan Xu  // -------------------------------------------------
906e91cacaSYinan Xu  private val l3_xbar = TLXbar()
916e91cacaSYinan Xu
9297eae8a0SWang Huizhe  private val l3_node = LazyModule(new InclusiveCache(
936e91cacaSYinan Xu    CacheParameters(
946e91cacaSYinan Xu      level = 3,
956e91cacaSYinan Xu      ways = L3NWays,
966e91cacaSYinan Xu      sets = L3NSets,
976e91cacaSYinan Xu      blockBytes = L3BlockSize,
986e91cacaSYinan Xu      beatBytes = L2BusWidth / 8,
9997eae8a0SWang Huizhe      cacheName = "L3"
1006e91cacaSYinan Xu    ),
1016e91cacaSYinan Xu    InclusiveCacheMicroParameters(
1028d9f4ff7SAllen      writeBytes = 32
1036e91cacaSYinan Xu    )
10497eae8a0SWang Huizhe  )).node
1056e91cacaSYinan Xu
1065d65f258SYinan Xu  // L3 to memory network
1075d65f258SYinan Xu  // -------------------------------------------------
1085d65f258SYinan Xu  private val memory_xbar = TLXbar()
1095d65f258SYinan Xu  private val mmioXbar = TLXbar()
1105d65f258SYinan Xu
1115d65f258SYinan Xu  // only mem, dma and extDev are visible externally
1125d65f258SYinan Xu  val mem = Seq.fill(L3NBanks)(AXI4IdentityNode())
1135d65f258SYinan Xu  val dma = AXI4IdentityNode()
1145d65f258SYinan Xu  val extDev = AXI4IdentityNode()
1155d65f258SYinan Xu
1165d65f258SYinan Xu  // connections
1175d65f258SYinan Xu  // -------------------------------------------------
1185d65f258SYinan Xu  for (i <- 0 until NumCores) {
1190cff4510SAllen    l2_xbar(i) := TLBuffer() := DebugIdentityNode() := xs_core(i).memBlock.dcache.clientNode
1205d65f258SYinan Xu    l2_xbar(i) := TLBuffer() := DebugIdentityNode() := xs_core(i).l1pluscache.clientNode
1215d65f258SYinan Xu    l2_xbar(i) := TLBuffer() := DebugIdentityNode() := xs_core(i).ptw.node
12287b0fcb0Szhanglinjuan    l2_xbar(i) := TLBuffer() := DebugIdentityNode() := l2prefetcher(i).clientNode
12387b0fcb0Szhanglinjuan
1240cff4510SAllen    mmioXbar   := TLBuffer() := DebugIdentityNode() := xs_core(i).memBlock.uncache.clientNode
125220f98bbSjinyue110    mmioXbar   := TLBuffer() := DebugIdentityNode() := xs_core(i).frontend.instrUncache.clientNode
126279a83c2SAllen    l2cache(i).node := DataDontCareNode(a = true, b = true) := TLBuffer() := DebugIdentityNode() := l2_xbar(i)
1275d65f258SYinan Xu    l3_xbar := TLBuffer() := DebugIdentityNode() := l2cache(i).node
1285d65f258SYinan Xu  }
1296e91cacaSYinan Xu
1306e91cacaSYinan Xu  // DMA should not go to MMIO
1316e91cacaSYinan Xu  val mmioRange = AddressSet(base = 0x0000000000L, mask = 0x007fffffffL)
1326e91cacaSYinan Xu  // AXI4ToTL needs a TLError device to route error requests,
1336e91cacaSYinan Xu  // add one here to make it happy.
1346e91cacaSYinan Xu  val tlErrorParams = DevNullParams(
1356e91cacaSYinan Xu    address = Seq(mmioRange),
1366e91cacaSYinan Xu    maxAtomic = 8,
1376e91cacaSYinan Xu    maxTransfer = 64)
1386e91cacaSYinan Xu  val tlError = LazyModule(new TLError(params = tlErrorParams, beatBytes = L2BusWidth / 8))
1396e91cacaSYinan Xu  private val tlError_xbar = TLXbar()
1406e91cacaSYinan Xu  tlError_xbar :=
1416e91cacaSYinan Xu    AXI4ToTL() :=
1426e91cacaSYinan Xu    AXI4UserYanker(Some(1)) :=
1436e91cacaSYinan Xu    AXI4Fragmenter() :=
1446e91cacaSYinan Xu    AXI4IdIndexer(1) :=
1456e91cacaSYinan Xu    dma
1466e91cacaSYinan Xu  tlError.node := tlError_xbar
1476e91cacaSYinan Xu
1486e91cacaSYinan Xu  l3_xbar :=
1496e91cacaSYinan Xu    TLBuffer() :=
1506e91cacaSYinan Xu    DebugIdentityNode() :=
1516e91cacaSYinan Xu    tlError_xbar
1526e91cacaSYinan Xu
15397eae8a0SWang Huizhe  val bankedNode =
15497eae8a0SWang Huizhe    BankBinder(L3NBanks, L3BlockSize) :*= l3_node :*= TLBuffer() :*= DebugIdentityNode() :*= l3_xbar
1556e91cacaSYinan Xu
1566e91cacaSYinan Xu  for(i <- 0 until L3NBanks) {
1576e91cacaSYinan Xu    mem(i) :=
1586e91cacaSYinan Xu      AXI4UserYanker() :=
1596e91cacaSYinan Xu      TLToAXI4() :=
1606e91cacaSYinan Xu      TLWidthWidget(L3BusWidth / 8) :=
161953a0310SLinJiawei      TLBuffer() :=
1626e91cacaSYinan Xu      TLCacheCork() :=
16397eae8a0SWang Huizhe      bankedNode
1646e91cacaSYinan Xu  }
1656e91cacaSYinan Xu
1663e586e47Slinjiawei  private val clint = LazyModule(new TLTimer(
1673e586e47Slinjiawei    Seq(AddressSet(0x38000000L, 0x0000ffffL)),
1683e586e47Slinjiawei    sim = !env.FPGAPlatform
1693e586e47Slinjiawei  ))
1703e586e47Slinjiawei
1715d65f258SYinan Xu  clint.node := mmioXbar
1725d65f258SYinan Xu  extDev := AXI4UserYanker() := TLToAXI4() := mmioXbar
1733e586e47Slinjiawei
1740584d3a8SLinJiawei  val fakeTreeNode = new GenericLogicalTreeNode
1750584d3a8SLinJiawei
1760584d3a8SLinJiawei  val beu = LazyModule(
1779637c0c6SLinJiawei    new BusErrorUnit(new XSL1BusErrors(NumCores), BusErrorUnitParams(0x38010000), fakeTreeNode))
1780584d3a8SLinJiawei  beu.node := mmioXbar
1790584d3a8SLinJiawei
1800584d3a8SLinJiawei  class BeuSinkNode()(implicit p: Parameters) extends LazyModule {
1810584d3a8SLinJiawei    val intSinkNode = IntSinkNode(IntSinkPortSimple())
1820584d3a8SLinJiawei    lazy val module = new LazyModuleImp(this){
1830584d3a8SLinJiawei      val interrupt = IO(Output(Bool()))
1840584d3a8SLinJiawei      interrupt := intSinkNode.in.head._1.head
1850584d3a8SLinJiawei    }
1860584d3a8SLinJiawei  }
1870584d3a8SLinJiawei  val beuSink = LazyModule(new BeuSinkNode())
1880584d3a8SLinJiawei  beuSink.intSinkNode := beu.intNode
1890584d3a8SLinJiawei
1904a26299eSwangkaifan  val plic = LazyModule(new AXI4Plic(
1914a26299eSwangkaifan    Seq(AddressSet(0x3c000000L, 0x03ffffffL)),
1924a26299eSwangkaifan    sim = !env.FPGAPlatform
1934a26299eSwangkaifan  ))
1940584d3a8SLinJiawei  plic.node := AXI4UserYanker() := TLToAXI4() := mmioXbar
1954a26299eSwangkaifan
1963e586e47Slinjiawei  lazy val module = new LazyModuleImp(this){
197006e1884SZihao Yu    val io = IO(new Bundle{
19884eb3d54SYinan Xu      val extIntrs = Input(UInt(NrExtIntr.W))
1994a26299eSwangkaifan      // val meip = Input(Vec(NumCores, Bool()))
200a428082bSLinJiawei      val ila = if(env.FPGAPlatform && EnableILA) Some(Output(new ILABundle)) else None
201006e1884SZihao Yu    })
202a165bd69Swangkaifan    val difftestIO0 = IO(new DifftestBundle())
203a165bd69Swangkaifan    val difftestIO1 = IO(new DifftestBundle())
204a165bd69Swangkaifan    val difftestIO = Seq(difftestIO0, difftestIO1)
2055f00f642Swangkaifan
2065f00f642Swangkaifan    val trapIO0 = IO(new xiangshan.TrapIO())
2075f00f642Swangkaifan    val trapIO1 = IO(new xiangshan.TrapIO())
2085f00f642Swangkaifan    val trapIO = Seq(trapIO0, trapIO1)
2095f00f642Swangkaifan
2100584d3a8SLinJiawei    plic.module.io.extra.get.intrVec <> RegNext(beuSink.module.interrupt)
2114a26299eSwangkaifan
2125d65f258SYinan Xu    for (i <- 0 until NumCores) {
2137a77cff2SYinan Xu      xs_core(i).module.io.hartId := i.U
2140668d426Swangkaifan      xs_core(i).module.io.externalInterrupt.mtip := clint.module.io.mtip(i)
2150668d426Swangkaifan      xs_core(i).module.io.externalInterrupt.msip := clint.module.io.msip(i)
216*4e3ce935Sljw      beu.module.io.errors.l1plus(i) := RegNext(xs_core(i).module.io.l1plus_error)
2172e3a956eSLinJiawei      beu.module.io.errors.icache(i) := RegNext(xs_core(i).module.io.icache_error)
2182e3a956eSLinJiawei      beu.module.io.errors.dcache(i) := RegNext(xs_core(i).module.io.dcache_error)
2194a26299eSwangkaifan      // xs_core(i).module.io.externalInterrupt.meip := RegNext(RegNext(io.meip(i)))
2204a26299eSwangkaifan      xs_core(i).module.io.externalInterrupt.meip := plic.module.io.extra.get.meip(i)
22192a86cc7Sljw      l2prefetcher(i).module.io.enable := RegNext(xs_core(i).module.io.l2_pf_enable)
22221377543Szhanglinjuan      l2prefetcher(i).module.io.in <> l2cache(i).module.io
2235d65f258SYinan Xu    }
22421377543Szhanglinjuan
225a165bd69Swangkaifan    difftestIO0 <> xs_core(0).module.difftestIO
2263d499721Swangkaifan    difftestIO1 <> DontCare
2275f00f642Swangkaifan    trapIO0 <> xs_core(0).module.trapIO
2283d499721Swangkaifan    trapIO1 <> DontCare
2293d499721Swangkaifan
2303d499721Swangkaifan    if (env.DualCore) {
2313d499721Swangkaifan      difftestIO1 <> xs_core(1).module.difftestIO
2325f00f642Swangkaifan      trapIO1 <> xs_core(1).module.trapIO
233a165bd69Swangkaifan    }
2341e1cfa36SAllen    // do not let dma AXI signals optimized out
23584eb3d54SYinan Xu    dontTouch(dma.out.head._1)
23684eb3d54SYinan Xu    dontTouch(extDev.out.head._1)
23784eb3d54SYinan Xu    dontTouch(io.extIntrs)
238006e1884SZihao Yu  }
2393e586e47Slinjiawei
2403e586e47Slinjiawei}
241