xref: /XiangShan/src/main/scala/system/SoC.scala (revision 49272fa467f97c3293eb9ed685e99ecf79691182)
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  NumCores: Integer = 1,
20  EnableILA: Boolean = false,
21  HasL2Cache: Boolean = false,
22  HasPrefetch: Boolean = false
23)
24
25trait HasSoCParameter extends HasXSParameter{
26  val soc = top.Parameters.get.socParameters
27  val NumCores = soc.NumCores
28  val EnableILA = soc.EnableILA
29  val HasL2cache = soc.HasL2Cache
30  val HasPrefetch = soc.HasPrefetch
31}
32
33class ILABundle extends Bundle {}
34
35
36class DummyCore()(implicit p: Parameters) extends LazyModule {
37  val mem = TLFuzzer(nOperations = 10)
38  val mmio = TLFuzzer(nOperations = 10)
39
40  lazy val module = new LazyModuleImp(this){
41
42  }
43}
44
45
46class XSSoc()(implicit p: Parameters) extends LazyModule with HasSoCParameter {
47  // CPU Cores
48  private val xs_core = Seq.fill(NumCores)(LazyModule(new XSCore()))
49
50  // L1 to L2 network
51  // -------------------------------------------------
52  private val l2_xbar = Seq.fill(NumCores)(TLXbar())
53
54  private val l2cache = Seq.fill(NumCores)(LazyModule(new InclusiveCache(
55    CacheParameters(
56      level = 2,
57      ways = L2NWays,
58      sets = L2NSets,
59      blockBytes = L2BlockSize,
60      beatBytes = L1BusWidth / 8, // beatBytes = l1BusDataWidth / 8
61      cacheName = s"L2"
62    ),
63    InclusiveCacheMicroParameters(
64      writeBytes = 8
65    )
66  )))
67
68  // L2 to L3 network
69  // -------------------------------------------------
70  private val l3_xbar = TLXbar()
71
72  private val l3_banks = (0 until L3NBanks) map (i =>
73      LazyModule(new InclusiveCache(
74        CacheParameters(
75          level = 3,
76          ways = L3NWays,
77          sets = L3NSets,
78          blockBytes = L3BlockSize,
79          beatBytes = L2BusWidth / 8,
80          cacheName = s"L3_$i"
81        ),
82      InclusiveCacheMicroParameters(
83        writeBytes = 8
84      )
85    )))
86
87  // L3 to memory network
88  // -------------------------------------------------
89  private val memory_xbar = TLXbar()
90  private val mmioXbar = TLXbar()
91
92  // only mem, dma and extDev are visible externally
93  val mem = Seq.fill(L3NBanks)(AXI4IdentityNode())
94  val dma = AXI4IdentityNode()
95  val extDev = AXI4IdentityNode()
96
97  // connections
98  // -------------------------------------------------
99  for (i <- 0 until NumCores) {
100    l2_xbar(i) := TLBuffer() := DebugIdentityNode() := xs_core(i).dcache.clientNode
101    l2_xbar(i) := TLBuffer() := DebugIdentityNode() := xs_core(i).l1pluscache.clientNode
102    l2_xbar(i) := TLBuffer() := DebugIdentityNode() := xs_core(i).ptw.node
103    mmioXbar   := TLBuffer() := DebugIdentityNode() := xs_core(i).uncache.clientNode
104    l2cache(i).node := TLBuffer() := DebugIdentityNode() := l2_xbar(i)
105    l3_xbar := TLBuffer() := DebugIdentityNode() := l2cache(i).node
106  }
107
108  // DMA should not go to MMIO
109  val mmioRange = AddressSet(base = 0x0000000000L, mask = 0x007fffffffL)
110  // AXI4ToTL needs a TLError device to route error requests,
111  // add one here to make it happy.
112  val tlErrorParams = DevNullParams(
113    address = Seq(mmioRange),
114    maxAtomic = 8,
115    maxTransfer = 64)
116  val tlError = LazyModule(new TLError(params = tlErrorParams, beatBytes = L2BusWidth / 8))
117  private val tlError_xbar = TLXbar()
118  tlError_xbar :=
119    AXI4ToTL() :=
120    AXI4UserYanker(Some(1)) :=
121    AXI4Fragmenter() :=
122    AXI4IdIndexer(1) :=
123    dma
124  tlError.node := tlError_xbar
125
126  l3_xbar :=
127    TLBuffer() :=
128    DebugIdentityNode() :=
129    tlError_xbar
130
131  def bankFilter(bank: Int) = AddressSet(
132    base = bank * L3BlockSize,
133    mask = ~BigInt((L3NBanks -1) * L3BlockSize))
134
135  for(i <- 0 until L3NBanks) {
136    val filter = TLFilter(TLFilter.mSelectIntersect(bankFilter(i)))
137    l3_banks(i).node := TLBuffer() := DebugIdentityNode() := filter := l3_xbar
138  }
139
140  for(i <- 0 until L3NBanks) {
141    mem(i) :=
142      AXI4UserYanker() :=
143      TLToAXI4() :=
144      TLWidthWidget(L3BusWidth / 8) :=
145      TLCacheCork() :=
146      l3_banks(i).node
147  }
148
149  private val clint = LazyModule(new TLTimer(
150    Seq(AddressSet(0x38000000L, 0x0000ffffL)),
151    sim = !env.FPGAPlatform
152  ))
153
154  clint.node := mmioXbar
155  extDev := AXI4UserYanker() := TLToAXI4() := mmioXbar
156
157  lazy val module = new LazyModuleImp(this){
158    val io = IO(new Bundle{
159      val meip = Input(Bool())
160      val ila = if(env.FPGAPlatform && EnableILA) Some(Output(new ILABundle)) else None
161    })
162    for (i <- 0 until NumCores) {
163      xs_core(i).module.io.externalInterrupt.mtip := clint.module.io.mtip
164      xs_core(i).module.io.externalInterrupt.msip := clint.module.io.msip
165      xs_core(i).module.io.externalInterrupt.meip := RegNext(RegNext(io.meip))
166    }
167    // do not let dma AXI signals optimized out
168    chisel3.dontTouch(dma.out.head._1)
169    chisel3.dontTouch(extDev.out.head._1)
170  }
171
172}
173