xref: /XiangShan/src/main/scala/top/Top.scala (revision d479a3a838f93713e8d569af098b6da7fc3c5905)
1package top
2
3import chisel3._
4import chisel3.util._
5import xiangshan._
6import system._
7import chisel3.stage.ChiselGeneratorAnnotation
8import chipsalliance.rocketchip.config
9import device.{TLTimer, AXI4Plic}
10import freechips.rocketchip.diplomacy._
11import freechips.rocketchip.tilelink._
12import freechips.rocketchip.amba.axi4._
13import freechips.rocketchip.devices.tilelink.{DevNullParams, TLError}
14import sifive.blocks.inclusivecache._
15import xiangshan.cache.prefetch.L2Prefetcher
16
17
18abstract class BaseXSSoc()(implicit p: config.Parameters) extends LazyModule with HasSoCParameter {
19  val bankedNode = BankBinder(L3NBanks, L3BlockSize)
20  val peripheralXbar = TLXbar()
21  val l3_xbar = TLXbar()
22}
23
24// We adapt the following three traits from rocket-chip.
25// Source: rocket-chip/src/main/scala/subsystem/Ports.scala
26trait HaveSlaveAXI4Port {
27  this: BaseXSSoc =>
28
29  val idBits = 16
30
31  val l3FrontendAXI4Node = AXI4MasterNode(Seq(AXI4MasterPortParameters(
32    Seq(AXI4MasterParameters(
33      name = "dma",
34      id = IdRange(0, 1 << idBits)
35    ))
36  )))
37  private val errorDevice = LazyModule(new TLError(
38    params = DevNullParams(
39      address = Seq(AddressSet(0x0, 0x7fffffffL)),
40      maxAtomic = 8,
41      maxTransfer = 64),
42    beatBytes = L2BusWidth / 8
43  ))
44  private val error_xbar = TLXbar()
45
46  error_xbar :=
47    AXI4ToTL() :=
48    AXI4UserYanker(Some(1)) :=
49    AXI4Fragmenter() :=
50    AXI4IdIndexer(1) :=
51    l3FrontendAXI4Node
52  errorDevice.node := error_xbar
53  l3_xbar :=
54    TLBuffer() :=
55    error_xbar
56
57  val dma = InModuleBody {
58    l3FrontendAXI4Node.makeIOs()
59  }
60}
61
62trait HaveAXI4MemPort {
63  this: BaseXSSoc =>
64  // 40-bit physical address
65  val memRange = AddressSet(0x00000000L, 0xffffffffffL).subtract(AddressSet(0x0L, 0x7fffffffL))
66  val memAXI4SlaveNode = AXI4SlaveNode(Seq.tabulate(L3NBanks) { i =>
67    AXI4SlavePortParameters(
68      slaves = Seq(
69        AXI4SlaveParameters(
70          address = memRange,
71          regionType = RegionType.UNCACHED,
72          executable = true,
73          supportsRead = TransferSizes(1, L3BlockSize),
74          supportsWrite = TransferSizes(1, L3BlockSize),
75          interleavedId = Some(0)
76        )
77      ),
78      beatBytes = L3BusWidth / 8
79    )
80  })
81
82  memAXI4SlaveNode :=*
83    AXI4UserYanker() :=*
84    AXI4IdIndexer(12) :=*
85    TLToAXI4() :=*
86    TLWidthWidget(L3BusWidth / 8) :=*
87    TLCacheCork() :=*
88    bankedNode
89
90  val memory = InModuleBody {
91    memAXI4SlaveNode.makeIOs()
92  }
93}
94
95
96trait HaveAXI4PeripheralPort { this: BaseXSSoc =>
97  // on-chip devices: 0x3800_000 - 0x3fff_ffff
98  val onChipPeripheralRange = AddressSet(0x38000000L, 0x07ffffffL)
99  val peripheralRange = AddressSet(0x0, 0x7fffffff).subtract(onChipPeripheralRange)
100  val peripheralNode = AXI4SlaveNode(Seq(AXI4SlavePortParameters(
101    Seq(AXI4SlaveParameters(
102      address = peripheralRange,
103      regionType = RegionType.UNCACHED,
104      supportsRead = TransferSizes(1, 8),
105      supportsWrite = TransferSizes(1, 8),
106      interleavedId = Some(0)
107    )),
108    beatBytes = 8
109  )))
110
111  peripheralNode :=
112    AXI4UserYanker() :=
113    AXI4IdIndexer(14) :=*
114    TLToAXI4() :=
115    peripheralXbar
116
117  val peripheral = InModuleBody {
118    peripheralNode.makeIOs()
119  }
120
121}
122
123
124class XSTop()(implicit p: config.Parameters) extends BaseXSSoc()
125  with HaveAXI4MemPort
126  with HaveAXI4PeripheralPort
127  with HaveSlaveAXI4Port
128  {
129
130  println(s"FPGASoC cores: $NumCores banks: $L3NBanks block size: $L3BlockSize bus size: $L3BusWidth")
131
132  val core = Seq.fill(NumCores)(LazyModule(new XSCore()))
133  val l2prefetcher = Seq.fill(NumCores)(LazyModule(new L2Prefetcher()))
134  val l2cache = Seq.fill(NumCores)(LazyModule(new InclusiveCache(
135    CacheParameters(
136      level = 2,
137      ways = L2NWays,
138      sets = L2NSets,
139      blockBytes = L2BlockSize,
140      beatBytes = L1BusWidth / 8, // beatBytes = l1BusDataWidth / 8
141      cacheName = s"L2"
142    ),
143    InclusiveCacheMicroParameters(
144      writeBytes = 32
145    )
146  )))
147  val l2xbar = Seq.fill(NumCores)(TLXbar())
148
149  for (i <- 0 until NumCores) {
150    peripheralXbar := TLBuffer() := core(i).frontend.instrUncache.clientNode
151    peripheralXbar := TLBuffer() := core(i).memBlock.uncache.clientNode
152    l2xbar(i) := TLBuffer() := core(i).memBlock.dcache.clientNode
153    l2xbar(i) := TLBuffer() := core(i).l1pluscache.clientNode
154    l2xbar(i) := TLBuffer() := core(i).ptw.node
155    l2xbar(i) := TLBuffer() := l2prefetcher(i).clientNode
156    l2cache(i).node := TLBuffer() := l2xbar(i)
157    l3_xbar := TLBuffer() := l2cache(i).node
158  }
159
160  private val clint = LazyModule(new TLTimer(
161    Seq(AddressSet(0x38000000L, 0x0000ffffL)),
162    sim = !env.FPGAPlatform
163  ))
164  clint.node := peripheralXbar
165
166  val plic = LazyModule(new AXI4Plic(
167    Seq(AddressSet(0x3c000000L, 0x03ffffffL)),
168    sim = !env.FPGAPlatform
169  ))
170  plic.node := AXI4IdentityNode() := AXI4UserYanker() := TLToAXI4() := peripheralXbar
171
172  val l3cache = LazyModule(new InclusiveCache(
173    CacheParameters(
174      level = 3,
175      ways = L3NWays,
176      sets = L3NSets,
177      blockBytes = L3BlockSize,
178      beatBytes = L2BusWidth / 8,
179      cacheName = "L3"
180    ),
181    InclusiveCacheMicroParameters(
182      writeBytes = 32
183    )
184  )).node
185
186  bankedNode :*= l3cache :*= TLBuffer() :*= l3_xbar
187
188  lazy val module = new LazyModuleImp(this) {
189    val io = IO(new Bundle {
190      val extIntrs = Input(UInt(NrExtIntr.W))
191      // val meip = Input(Vec(NumCores, Bool()))
192      val ila = if(env.FPGAPlatform && EnableILA) Some(Output(new ILABundle)) else None
193    })
194
195    plic.module.io.extra.get.intrVec <> RegNext(RegNext(io.extIntrs))
196
197    for (i <- 0 until NumCores) {
198      core(i).module.io.hartId := i.U
199      core(i).module.io.externalInterrupt.mtip := clint.module.io.mtip(i)
200      core(i).module.io.externalInterrupt.msip := clint.module.io.msip(i)
201      core(i).module.io.externalInterrupt.meip := plic.module.io.extra.get.meip(i)
202      l2prefetcher(i).module.io.enable := RegNext(core(i).module.io.l2_pf_enable)
203      l2prefetcher(i).module.io.in <> l2cache(i).module.io
204    }
205
206    dontTouch(io.extIntrs)
207  }
208}
209
210object TopMain extends App {
211  override def main(args: Array[String]): Unit = {
212    Parameters.set(
213      args.contains("--dual-core") match {
214        case false => Parameters()
215        case true  => Parameters.dualCoreParameters
216      }
217    )
218    val otherArgs = args.filterNot(_ == "--dual-core")
219    implicit val p = config.Parameters.empty
220    XiangShanStage.execute(otherArgs, Seq(
221      ChiselGeneratorAnnotation(() => {
222        val soc = LazyModule(new XSTop())
223        soc.module
224      })
225    ))
226  }
227}
228