xref: /XiangShan/src/main/scala/system/SoC.scala (revision ab3aa7eedc9c70d560572701ea30e863011452a8)
1package system
2
3import chipsalliance.rocketchip.config.Parameters
4import device.{AXI4Timer, TLTimer}
5import chisel3._
6import chisel3.util._
7import freechips.rocketchip.diplomacy.{AddressSet, LazyModule, LazyModuleImp}
8import freechips.rocketchip.tilelink.{TLBuffer, TLFuzzer, TLIdentityNode, TLXbar}
9import utils.DebugIdentityNode
10import xiangshan.{HasXSParameter, XSCore}
11import sifive.blocks.inclusivecache.{CacheParameters, InclusiveCache, InclusiveCacheMicroParameters}
12import freechips.rocketchip.diplomacy.{LazyModule, LazyModuleImp, AddressSet}
13import freechips.rocketchip.tilelink.{TLBundleParameters, TLCacheCork, TLBuffer, TLClientNode, TLIdentityNode, TLXbar, TLWidthWidget, TLFilter, TLToAXI4}
14import freechips.rocketchip.devices.tilelink.{TLError, DevNullParams}
15import freechips.rocketchip.amba.axi4.{AXI4ToTL, AXI4IdentityNode, AXI4UserYanker, AXI4Fragmenter, AXI4IdIndexer, AXI4Deinterleaver}
16
17case class SoCParameters
18(
19  EnableILA: Boolean = false,
20  HasL2Cache: Boolean = false,
21  HasPrefetch: Boolean = false
22)
23
24trait HasSoCParameter extends HasXSParameter{
25  val soc = top.Parameters.get.socParameters
26  val EnableILA = soc.EnableILA
27  val HasL2cache = soc.HasL2Cache
28  val HasPrefetch = soc.HasPrefetch
29}
30
31class ILABundle extends Bundle {}
32
33
34class DummyCore()(implicit p: Parameters) extends LazyModule {
35  val mem = TLFuzzer(nOperations = 10)
36  val mmio = TLFuzzer(nOperations = 10)
37
38  lazy val module = new LazyModuleImp(this){
39
40  }
41}
42
43
44class XSSoc()(implicit p: Parameters) extends LazyModule with HasSoCParameter {
45  val numCores = 1
46
47  private val cores = Seq.fill(numCores)(LazyModule(new XSCore()))
48
49  // only mem and extDev visible externally
50  val dma = AXI4IdentityNode()
51  val extDev = TLIdentityNode()
52
53  // L2 to L3 network
54  // -------------------------------------------------
55  private val l3_xbar = TLXbar()
56
57  private val l3_banks = (0 until L3NBanks) map (i =>
58      LazyModule(new InclusiveCache(
59        CacheParameters(
60          level = 3,
61          ways = L3NWays,
62          sets = L3NSets,
63          blockBytes = L3BlockSize,
64          beatBytes = L2BusWidth / 8,
65          cacheName = s"L3_$i"
66        ),
67      InclusiveCacheMicroParameters(
68        writeBytes = 8
69      )
70    )))
71
72  cores.foreach(core => l3_xbar := TLBuffer() := DebugIdentityNode() := core.mem)
73
74  // DMA should not go to MMIO
75  val mmioRange = AddressSet(base = 0x0000000000L, mask = 0x007fffffffL)
76  // AXI4ToTL needs a TLError device to route error requests,
77  // add one here to make it happy.
78  val tlErrorParams = DevNullParams(
79    address = Seq(mmioRange),
80    maxAtomic = 8,
81    maxTransfer = 64)
82  val tlError = LazyModule(new TLError(params = tlErrorParams, beatBytes = L2BusWidth / 8))
83  private val tlError_xbar = TLXbar()
84  tlError_xbar :=
85    AXI4ToTL() :=
86    AXI4UserYanker(Some(1)) :=
87    AXI4Fragmenter() :=
88    AXI4IdIndexer(1) :=
89    dma
90  tlError.node := tlError_xbar
91
92  l3_xbar :=
93    TLBuffer() :=
94    DebugIdentityNode() :=
95    tlError_xbar
96
97  def bankFilter(bank: Int) = AddressSet(
98    base = bank * L3BlockSize,
99    mask = ~BigInt((L3NBanks -1) * L3BlockSize))
100
101  for(i <- 0 until L3NBanks) {
102    val filter = TLFilter(TLFilter.mSelectIntersect(bankFilter(i)))
103    l3_banks(i).node := TLBuffer() := DebugIdentityNode() := filter := l3_xbar
104  }
105
106
107  // L3 to memory network
108  // -------------------------------------------------
109  private val memory_xbar = TLXbar()
110
111  val mem = Seq.fill(L3NBanks)(AXI4IdentityNode())
112  for(i <- 0 until L3NBanks) {
113    mem(i) :=
114      AXI4UserYanker() :=
115      TLToAXI4() :=
116      TLWidthWidget(L3BusWidth / 8) :=
117      TLCacheCork() :=
118      l3_banks(i).node
119  }
120
121  private val mmioXbar = TLXbar()
122  private val clint = LazyModule(new TLTimer(
123    Seq(AddressSet(0x38000000L, 0x0000ffffL)),
124    sim = !env.FPGAPlatform
125  ))
126
127  cores.foreach(core =>
128    mmioXbar :=
129    TLBuffer() :=
130    DebugIdentityNode() :=
131    core.mmio
132  )
133
134  clint.node :=
135    mmioXbar
136
137  extDev :=
138    mmioXbar
139
140  lazy val module = new LazyModuleImp(this){
141    val io = IO(new Bundle{
142      val meip = Input(Bool())
143      val ila = if(env.FPGAPlatform && EnableILA) Some(Output(new ILABundle)) else None
144    })
145    cores.foreach(core => {
146      core.module.io.externalInterrupt.mtip := clint.module.io.mtip
147      core.module.io.externalInterrupt.msip := clint.module.io.msip
148      core.module.io.externalInterrupt.meip := RegNext(RegNext(io.meip))
149    })
150  }
151
152}
153
154
155//class XSSoc extends Module with HasSoCParameter {
156//  val io = IO(new Bundle{
157//    val mem = new TLCached(l1BusParams)
158//    val mmio = new TLCached(l1BusParams)
159//    val frontend = Flipped(new AXI4) //TODO: do we need it ?
160//    val meip = Input(Bool())
161//    val ila = if (env.FPGAPlatform && EnableILA) Some(Output(new ILABundle)) else None
162//  })
163//
164//  val xsCore = Module(new XSCore)
165//
166//  io.frontend <> DontCare
167//
168//  io.mem <> xsCore.io.mem
169//
170//  val addrSpace = List(
171//    (0x40000000L, 0x40000000L), // external devices
172//    (0x38000000L, 0x00010000L)  // CLINT
173//  )
174//  val mmioXbar = Module(new NaiveTL1toN(addrSpace, xsCore.io.mem.params))
175//  mmioXbar.io.in <> xsCore.io.mmio
176//
177//  val extDev = mmioXbar.io.out(0)
178//  val clint = Module(new AXI4Timer(sim = !env.FPGAPlatform))
179//  clint.io.in <> AXI4ToAXI4Lite(MMIOTLToAXI4(mmioXbar.io.out(1)))
180//
181//  io.mmio <> extDev
182//
183//  val mtipSync = clint.io.extra.get.mtip
184//  val meipSync = RegNext(RegNext(io.meip))
185//  ExcitingUtils.addSource(mtipSync, "mtip")
186//  ExcitingUtils.addSource(meipSync, "meip")
187//}
188