xref: /XiangShan/src/main/scala/top/Top.scala (revision b7b0d6c1ab6c9f4501f56975a1b95c01c7ec5983)
1package top
2
3import chisel3._
4import chisel3.util._
5import xiangshan._
6import utils._
7import system._
8import chisel3.stage.ChiselGeneratorAnnotation
9import chipsalliance.rocketchip.config
10import chipsalliance.rocketchip.config.Config
11import device.{AXI4Plic, TLTimer}
12import freechips.rocketchip.diplomacy._
13import freechips.rocketchip.tilelink._
14import freechips.rocketchip.amba.axi4._
15import freechips.rocketchip.devices.tilelink.{DevNullParams, TLError}
16import freechips.rocketchip.diplomaticobjectmodel.logicaltree.GenericLogicalTreeNode
17import freechips.rocketchip.interrupts.{IntSinkNode, IntSinkPortSimple}
18import freechips.rocketchip.tile.{BusErrorUnit, BusErrorUnitParams, XLen}
19import sifive.blocks.inclusivecache.{InclusiveCache, InclusiveCacheMicroParameters, CacheParameters}
20import xiangshan.cache.prefetch.L2Prefetcher
21
22
23class XSCoreWithL2()(implicit p: config.Parameters) extends LazyModule
24  with HasXSParameter {
25  private val core = LazyModule(new XSCore())
26  private val l2prefetcher = LazyModule(new L2Prefetcher())
27  private val l2xbar = TLXbar()
28
29  val l2cache = LazyModule(new InclusiveCache(
30    CacheParameters(
31      level = 2,
32      ways = L2NWays,
33      sets = L2NSets,
34      blockBytes = L2BlockSize,
35      beatBytes = L1BusWidth / 8, // beatBytes = l1BusDataWidth / 8
36      cacheName = s"L2",
37      uncachedGet = true,
38      enablePerf = false
39    ),
40    InclusiveCacheMicroParameters(
41      memCycles = 25,
42      writeBytes = 32
43    )
44  ))
45  val uncache = TLXbar()
46
47  l2xbar := TLBuffer() := core.memBlock.dcache.clientNode
48  l2xbar := TLBuffer() := core.l1pluscache.clientNode
49  l2xbar := TLBuffer() := core.ptw.node
50  l2xbar := TLBuffer() := l2prefetcher.clientNode
51  l2cache.node := TLBuffer() := l2xbar
52
53  uncache := TLBuffer() := core.frontend.instrUncache.clientNode
54  uncache := TLBuffer() := core.memBlock.uncache.clientNode
55
56  lazy val module = new LazyModuleImp(this) {
57    val io = IO(new Bundle {
58      val hartId = Input(UInt(64.W))
59      val externalInterrupt = new ExternalInterruptIO
60      val l1plus_error, icache_error, dcache_error = new L1CacheErrorInfo
61    })
62
63    core.module.io.hartId := io.hartId
64    core.module.io.externalInterrupt := io.externalInterrupt
65    l2prefetcher.module.io.enable := core.module.io.l2_pf_enable
66    l2prefetcher.module.io.in <> l2cache.module.io
67    io.l1plus_error <> core.module.io.l1plus_error
68    io.icache_error <> core.module.io.icache_error
69    io.dcache_error <> core.module.io.dcache_error
70
71    val core_reset_gen = Module(new ResetGen())
72    core.module.reset := core_reset_gen.io.out
73
74    val l2_reset_gen = Module(new ResetGen())
75    l2prefetcher.module.reset := l2_reset_gen.io.out
76    l2cache.module.reset := l2_reset_gen.io.out
77  }
78}
79
80abstract class BaseXSSoc()(implicit p: config.Parameters) extends LazyModule with HasSoCParameter {
81  val bankedNode = BankBinder(L3NBanks, L3BlockSize)
82  val peripheralXbar = TLXbar()
83  val l3_xbar = TLXbar()
84}
85
86// We adapt the following three traits from rocket-chip.
87// Source: rocket-chip/src/main/scala/subsystem/Ports.scala
88trait HaveSlaveAXI4Port {
89  this: BaseXSSoc =>
90
91  val idBits = 16
92
93  val l3FrontendAXI4Node = AXI4MasterNode(Seq(AXI4MasterPortParameters(
94    Seq(AXI4MasterParameters(
95      name = "dma",
96      id = IdRange(0, 1 << idBits)
97    ))
98  )))
99  private val errorDevice = LazyModule(new TLError(
100    params = DevNullParams(
101      address = Seq(AddressSet(0x0, 0x7fffffffL)),
102      maxAtomic = 8,
103      maxTransfer = 64),
104    beatBytes = L2BusWidth / 8
105  ))
106  private val error_xbar = TLXbar()
107
108  error_xbar :=
109    AXI4ToTL() :=
110    AXI4UserYanker(Some(1)) :=
111    AXI4Fragmenter() :=
112    AXI4IdIndexer(1) :=
113    l3FrontendAXI4Node
114  errorDevice.node := error_xbar
115  l3_xbar :=
116    TLBuffer() :=
117    error_xbar
118
119  val dma = InModuleBody {
120    l3FrontendAXI4Node.makeIOs()
121  }
122}
123
124trait HaveAXI4MemPort {
125  this: BaseXSSoc =>
126  // 40-bit physical address
127  val memRange = AddressSet(0x00000000L, 0xffffffffffL).subtract(AddressSet(0x0L, 0x7fffffffL))
128  val memAXI4SlaveNode = AXI4SlaveNode(Seq(
129    AXI4SlavePortParameters(
130      slaves = Seq(
131        AXI4SlaveParameters(
132          address = memRange,
133          regionType = RegionType.UNCACHED,
134          executable = true,
135          supportsRead = TransferSizes(1, L3BlockSize),
136          supportsWrite = TransferSizes(1, L3BlockSize),
137          interleavedId = Some(0)
138        )
139      ),
140      beatBytes = L3BusWidth / 8
141    )
142  ))
143
144  val mem_xbar = TLXbar()
145  mem_xbar :=* TLBuffer() :=* TLCacheCork() :=* bankedNode
146  memAXI4SlaveNode :=
147    AXI4UserYanker() :=
148    AXI4Deinterleaver(L3BlockSize) :=
149    TLToAXI4() :=
150    TLWidthWidget(L3BusWidth / 8) :=
151    mem_xbar
152
153  val memory = InModuleBody {
154    memAXI4SlaveNode.makeIOs()
155  }
156}
157
158
159trait HaveAXI4PeripheralPort { this: BaseXSSoc =>
160  // on-chip devices: 0x3800_000 - 0x3fff_ffff
161  val onChipPeripheralRange = AddressSet(0x38000000L, 0x07ffffffL)
162  val peripheralRange = AddressSet(0x0, 0x7fffffff).subtract(onChipPeripheralRange)
163  val peripheralNode = AXI4SlaveNode(Seq(AXI4SlavePortParameters(
164    Seq(AXI4SlaveParameters(
165      address = peripheralRange,
166      regionType = RegionType.UNCACHED,
167      supportsRead = TransferSizes(1, 8),
168      supportsWrite = TransferSizes(1, 8),
169      interleavedId = Some(0)
170    )),
171    beatBytes = 8
172  )))
173
174  peripheralNode :=
175    AXI4UserYanker() :=
176    AXI4Deinterleaver(8) :=
177    TLToAXI4() :=
178    peripheralXbar
179
180  val peripheral = InModuleBody {
181    peripheralNode.makeIOs()
182  }
183
184}
185
186
187class XSTop()(implicit p: config.Parameters) extends BaseXSSoc()
188  with HaveAXI4MemPort
189  with HaveAXI4PeripheralPort
190  with HaveSlaveAXI4Port
191{
192
193  println(s"FPGASoC cores: $NumCores banks: $L3NBanks block size: $L3BlockSize bus size: $L3BusWidth")
194
195  val core_with_l2 = Seq.fill(NumCores)(LazyModule(new XSCoreWithL2))
196
197  for (i <- 0 until NumCores) {
198    peripheralXbar := TLBuffer() := core_with_l2(i).uncache
199    l3_xbar := TLBuffer() := core_with_l2(i).l2cache.node
200  }
201
202  private val clint = LazyModule(new TLTimer(
203    Seq(AddressSet(0x38000000L, 0x0000ffffL)),
204    sim = !env.FPGAPlatform
205  ))
206  clint.node := peripheralXbar
207
208  val fakeTreeNode = new GenericLogicalTreeNode
209  val beu = LazyModule(
210    new BusErrorUnit(new XSL1BusErrors(NumCores), BusErrorUnitParams(0x38010000), fakeTreeNode))
211  beu.node := peripheralXbar
212
213  class BeuSinkNode()(implicit p: config.Parameters) extends LazyModule {
214    val intSinkNode = IntSinkNode(IntSinkPortSimple())
215    lazy val module = new LazyModuleImp(this){
216      val interrupt = IO(Output(Bool()))
217      interrupt := intSinkNode.in.head._1.head
218    }
219  }
220  val beuSink = LazyModule(new BeuSinkNode())
221  beuSink.intSinkNode := beu.intNode
222
223  val plic = LazyModule(new AXI4Plic(
224    Seq(AddressSet(0x3c000000L, 0x03ffffffL)),
225    sim = !env.FPGAPlatform
226  ))
227  plic.node := AXI4IdentityNode() := AXI4UserYanker() := TLToAXI4() := peripheralXbar
228
229  val l3cache = LazyModule(new InclusiveCache(
230    CacheParameters(
231      level = 3,
232      ways = L3NWays,
233      sets = L3NSets,
234      blockBytes = L3BlockSize,
235      beatBytes = L2BusWidth / 8,
236      cacheName = "L3",
237      uncachedGet = false,
238      enablePerf = false
239    ),
240    InclusiveCacheMicroParameters(
241      memCycles = 25,
242      writeBytes = 32
243    )
244  ))
245
246  bankedNode :*= l3cache.node :*= TLBuffer() :*= l3_xbar
247
248  lazy val module = new LazyRawModuleImp(this) {
249    val io = IO(new Bundle {
250      val clock = Input(Bool())
251      val reset = Input(Bool())
252      val extIntrs = Input(UInt(NrExtIntr.W))
253      // val meip = Input(Vec(NumCores, Bool()))
254      val ila = if(env.FPGAPlatform && EnableILA) Some(Output(new ILABundle)) else None
255    })
256    childClock := io.clock.asClock()
257
258    withClockAndReset(childClock, io.reset) {
259      val resetGen = Module(new ResetGen())
260      resetGen.suggestName("top_reset_gen")
261      childReset := resetGen.io.out
262    }
263
264    withClockAndReset(childClock, childReset) {
265      plic.module.io.extra.get.intrVec <> Cat(beuSink.module.interrupt, io.extIntrs)
266      require(io.extIntrs.getWidth + beuSink.module.interrupt.getWidth == NrPlicIntr)
267
268      for (i <- 0 until NumCores) {
269        val core_reset_gen = Module(new ResetGen())
270        core_reset_gen.suggestName(s"core_${i}_reset_gen")
271        core_with_l2(i).module.reset := core_reset_gen.io.out
272        core_with_l2(i).module.io.hartId := i.U
273        core_with_l2(i).module.io.externalInterrupt.mtip := clint.module.io.mtip(i)
274        core_with_l2(i).module.io.externalInterrupt.msip := clint.module.io.msip(i)
275        core_with_l2(i).module.io.externalInterrupt.meip := plic.module.io.extra.get.meip(i)
276        beu.module.io.errors.l1plus(i) := core_with_l2(i).module.io.l1plus_error
277        beu.module.io.errors.icache(i) := core_with_l2(i).module.io.icache_error
278        beu.module.io.errors.dcache(i) := core_with_l2(i).module.io.dcache_error
279      }
280
281      val l3_reset_gen = Module(new ResetGen())
282      l3_reset_gen.suggestName("l3_reset_gen")
283      l3cache.module.reset := l3_reset_gen.io.out
284    }
285  }
286}
287
288object TopMain extends App {
289  override def main(args: Array[String]): Unit = {
290    Parameters.set(
291      args.contains("--dual-core") match {
292        case false => Parameters()
293        case true  => Parameters.dualCoreParameters
294      }
295    )
296    val otherArgs = args.filterNot(_ == "--dual-core")
297    implicit val p = new Config((_, _, _) => {
298      case XLen => 64
299    })
300    XiangShanStage.execute(otherArgs, Seq(
301      ChiselGeneratorAnnotation(() => {
302        val soc = LazyModule(new XSTop())
303        soc.module
304      })
305    ))
306  }
307}
308