xref: /XiangShan/src/main/scala/device/standalone/StandAloneDevice.scala (revision 30e7906f14a3edf185b5aa20dae99b28489bcd9e)
1720dd621STang Haojin/***************************************************************************************
2720dd621STang Haojin* Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences
3720dd621STang Haojin* Copyright (c) 2020-2021 Peng Cheng Laboratory
4720dd621STang Haojin*
5720dd621STang Haojin* XiangShan is licensed under Mulan PSL v2.
6720dd621STang Haojin* You can use this software according to the terms and conditions of the Mulan PSL v2.
7720dd621STang Haojin* You may obtain a copy of Mulan PSL v2 at:
8720dd621STang Haojin*          http://license.coscl.org.cn/MulanPSL2
9720dd621STang Haojin*
10720dd621STang Haojin* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
11720dd621STang Haojin* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
12720dd621STang Haojin* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
13720dd621STang Haojin*
14720dd621STang Haojin* See the Mulan PSL v2 for more details.
15720dd621STang Haojin***************************************************************************************/
16720dd621STang Haojin
17720dd621STang Haojinpackage device.standalone
18720dd621STang Haojin
19720dd621STang Haojinimport chisel3._
20720dd621STang Haojinimport chisel3.util._
21b64156d0Ssinsanctionimport chisel3.experimental.{annotate, ChiselAnnotation}
224391123aSTang Haojinimport chisel3.experimental.dataview._
23720dd621STang Haojinimport freechips.rocketchip.diplomacy._
24720dd621STang Haojinimport org.chipsalliance.cde.config.Parameters
25720dd621STang Haojinimport freechips.rocketchip.devices.tilelink._
26720dd621STang Haojinimport freechips.rocketchip.amba.axi4._
27720dd621STang Haojinimport freechips.rocketchip.tilelink._
28720dd621STang Haojinimport top.Generator
29720dd621STang Haojinimport system.SoCParamsKey
30720dd621STang Haojinimport sifive.enterprise.firrtl.NestedPrefixModulesAnnotation
31720dd621STang Haojinimport scala.annotation.tailrec
32720dd621STang Haojinimport xiangshan.XSTileKey
334391123aSTang Haojinimport utils.VerilogAXI4Record
34720dd621STang Haojin
35720dd621STang Haojintrait HasMasterInterface { this: StandAloneDevice =>
36720dd621STang Haojin
37720dd621STang Haojin  protected val masternode = TLIdentityNode()
38720dd621STang Haojin  // tilelink master io
39720dd621STang Haojin  private val tlmaster = Option.when(useTL)(TLManagerNode(Seq(
40720dd621STang Haojin    TLSlavePortParameters.v1(
41720dd621STang Haojin      managers = Seq(
42720dd621STang Haojin        TLSlaveParameters.v1(
43720dd621STang Haojin          address = Seq(AddressSet(0, (BigInt(1) << addrWidth) - 1)),
44720dd621STang Haojin          regionType = RegionType.UNCACHED,
45720dd621STang Haojin          supportsGet = TransferSizes(1, p(SoCParamsKey).L3BlockSize),
46720dd621STang Haojin          supportsPutPartial = TransferSizes(1, p(SoCParamsKey).L3BlockSize),
47720dd621STang Haojin          supportsPutFull = TransferSizes(1, p(SoCParamsKey).L3BlockSize),
48720dd621STang Haojin          fifoId = Some(0)
49720dd621STang Haojin        )
50720dd621STang Haojin      ),
51720dd621STang Haojin      beatBytes = p(SoCParamsKey).L3OuterBusWidth / 8
52720dd621STang Haojin    )
53720dd621STang Haojin  )))
54720dd621STang Haojin  tlmaster.foreach(_ := masternode)
55720dd621STang Haojin  val tlmasternode = tlmaster.map(tlmaster => InModuleBody(tlmaster.makeIOs()))
56720dd621STang Haojin
57720dd621STang Haojin  // axi4 master io
58720dd621STang Haojin  private val axi4master = Option.when(!useTL)(AXI4SlaveNode(Seq(
59720dd621STang Haojin    AXI4SlavePortParameters(
60720dd621STang Haojin      slaves = Seq(
61720dd621STang Haojin        AXI4SlaveParameters(
62720dd621STang Haojin          address = Seq(AddressSet(0, (BigInt(1) << addrWidth) - 1)),
63720dd621STang Haojin          regionType = RegionType.UNCACHED,
64720dd621STang Haojin          supportsRead = TransferSizes(1, p(SoCParamsKey).L3BlockSize),
65720dd621STang Haojin          supportsWrite = TransferSizes(1, p(SoCParamsKey).L3BlockSize),
66720dd621STang Haojin          interleavedId = Some(0)
67720dd621STang Haojin        )
68720dd621STang Haojin      ),
69720dd621STang Haojin      beatBytes = p(SoCParamsKey).L3OuterBusWidth / 8
70720dd621STang Haojin    )
71720dd621STang Haojin  )))
72720dd621STang Haojin  axi4master.foreach(
73720dd621STang Haojin    _ :=
74720dd621STang Haojin      AXI4Buffer() :=
75720dd621STang Haojin      AXI4Buffer() :=
76720dd621STang Haojin      AXI4Buffer() :=
77720dd621STang Haojin      AXI4IdIndexer(1) :=
78720dd621STang Haojin      AXI4UserYanker() :=
79720dd621STang Haojin      AXI4Deinterleaver(p(SoCParamsKey).L3BlockSize) :=
80720dd621STang Haojin      TLToAXI4() :=
81720dd621STang Haojin      TLSourceShrinker(64) :=
82720dd621STang Haojin      TLWidthWidget(p(SoCParamsKey).L3OuterBusWidth / 8) :=
83720dd621STang Haojin      TLBuffer.chainNode(2) :=
84720dd621STang Haojin      masternode
85720dd621STang Haojin  )
864391123aSTang Haojin  val axi4masternode = axi4master.map(axi4master => InModuleBody {
87bb2f3f51STang Haojin    val axi4masternode = chisel3.IO(new VerilogAXI4Record(axi4master.in.head._1.params))
884391123aSTang Haojin    axi4masternode.viewAs[AXI4Bundle] <> axi4master.in.head._1
894391123aSTang Haojin    axi4masternode
904391123aSTang Haojin  })
91720dd621STang Haojin}
92720dd621STang Haojin
93720dd621STang Haojinabstract class StandAloneDevice (
94720dd621STang Haojin  val useTL: Boolean = false,
95720dd621STang Haojin  val baseAddress: BigInt,
96720dd621STang Haojin  val addrWidth: Int,
97720dd621STang Haojin  val dataWidth: Int,
98720dd621STang Haojin  val hartNum: Int
99720dd621STang Haojin)(implicit p: Parameters) extends LazyModule {
100720dd621STang Haojin
101720dd621STang Haojin  def addressSet: AddressSet
102720dd621STang Haojin
103720dd621STang Haojin  private val dummy = LazyModule(new TLError(
104720dd621STang Haojin    params = DevNullParams(
105720dd621STang Haojin      address = AddressSet(0, (BigInt(1) << addrWidth) - 1).subtract(addressSet),
106720dd621STang Haojin      maxAtomic = 8,
107720dd621STang Haojin      maxTransfer = 64
108720dd621STang Haojin    ),
109720dd621STang Haojin    beatBytes = dataWidth / 8
110720dd621STang Haojin  ))
111720dd621STang Haojin  protected val xbar = TLXbar()
112720dd621STang Haojin  dummy.node := xbar
113720dd621STang Haojin
114720dd621STang Haojin  // tilelink io
115720dd621STang Haojin  private val tl = Option.when(useTL)(TLClientNode(Seq(TLMasterPortParameters.v1(
116720dd621STang Haojin    Seq(TLMasterParameters.v1("tl", IdRange(0, 1)))
117720dd621STang Haojin  ))))
118720dd621STang Haojin  tl.foreach(xbar := _)
119720dd621STang Haojin  val tlnode = tl.map(tl => InModuleBody(tl.makeIOs()))
120720dd621STang Haojin
121720dd621STang Haojin  // axi4 io
122720dd621STang Haojin  private val axi4 = Option.when(!useTL)(AXI4MasterNode(Seq(AXI4MasterPortParameters(
123720dd621STang Haojin    Seq(AXI4MasterParameters("axi4", IdRange(0, 1)))
124720dd621STang Haojin  ))))
125720dd621STang Haojin  axi4.foreach(
126720dd621STang Haojin    xbar :=
127720dd621STang Haojin      TLFIFOFixer() :=
128720dd621STang Haojin      AXI4ToTL() :=
129720dd621STang Haojin      AXI4UserYanker(Some(1)) :=
130720dd621STang Haojin      AXI4Fragmenter() :=
131720dd621STang Haojin      AXI4Buffer() :=
132720dd621STang Haojin      AXI4Buffer() :=
133720dd621STang Haojin      AXI4IdIndexer(1) :=
134720dd621STang Haojin      _
135720dd621STang Haojin  )
1364391123aSTang Haojin  val axi4node = axi4.map(axi4 => InModuleBody {
137bb2f3f51STang Haojin    val axi4node = chisel3.IO(Flipped(new VerilogAXI4Record(axi4.out.head._1.params)))
1384391123aSTang Haojin    axi4node.viewAs[AXI4Bundle] <> axi4.out.head._1
1394391123aSTang Haojin    axi4node
1404391123aSTang Haojin  })
141720dd621STang Haojin
142b6ace320STang Haojin  lazy val module: LazyModuleImpLike = new StandAloneDeviceImp(this)
143720dd621STang Haojin
144720dd621STang Haojin}
145720dd621STang Haojin
146*30e7906fSHaojin Tangclass StandAloneDeviceImp(outer: StandAloneDevice)(implicit p: Parameters) extends LazyModuleImp(outer) with RequireAsyncReset {
147720dd621STang Haojin  p(SoCParamsKey).XSTopPrefix.foreach { prefix =>
148720dd621STang Haojin    val mod = this.toNamed
149720dd621STang Haojin    annotate(new ChiselAnnotation {
150720dd621STang Haojin      def toFirrtl = NestedPrefixModulesAnnotation(mod, prefix, true)
151720dd621STang Haojin    })
152720dd621STang Haojin  }
153720dd621STang Haojin}
154720dd621STang Haojin
155b6ace320STang Haojinclass StandAloneDeviceRawImp(outer: StandAloneDevice)(implicit p: Parameters) extends LazyRawModuleImp(outer) {
156b6ace320STang Haojin  p(SoCParamsKey).XSTopPrefix.foreach { prefix =>
157b6ace320STang Haojin    val mod = this.toNamed
158b6ace320STang Haojin    annotate(new ChiselAnnotation {
159b6ace320STang Haojin      def toFirrtl = NestedPrefixModulesAnnotation(mod, prefix, true)
160b6ace320STang Haojin    })
161b6ace320STang Haojin  }
162b6ace320STang Haojin}
163b6ace320STang Haojin
164720dd621STang Haojinobject ArgParser {
165720dd621STang Haojin  def parse(args: Array[String], p: Parameters): (StandAloneDevice, Array[String]) = {
166720dd621STang Haojin    var firrtlOpts = Array[String]()
167720dd621STang Haojin    var module: String = ""
168720dd621STang Haojin    var useTL: Boolean = false
169720dd621STang Haojin    var baseAddress: BigInt = -1
170720dd621STang Haojin    var addrWidth: Int = -1
171720dd621STang Haojin    var dataWidth: Int = 64
172720dd621STang Haojin    @tailrec
173720dd621STang Haojin    def nextOption(list: List[String]): Unit = {
174720dd621STang Haojin      list match {
175720dd621STang Haojin        case Nil =>
176720dd621STang Haojin        case "--standalone-device" :: value :: tail =>
177720dd621STang Haojin          module = value
178720dd621STang Haojin          nextOption(tail)
179720dd621STang Haojin        case "--use-tl" :: tail =>
180720dd621STang Haojin          useTL = true
181720dd621STang Haojin          nextOption(tail)
182720dd621STang Haojin        case "--use-axi4" :: tail =>
183720dd621STang Haojin          useTL = false
184720dd621STang Haojin          nextOption(tail)
185720dd621STang Haojin        case "--device-base-addr" :: value :: tail =>
186720dd621STang Haojin          baseAddress = value match {
187720dd621STang Haojin            case s"0x$hex" => BigInt(hex, 16)
188720dd621STang Haojin            case s"0X$hex" => BigInt(hex, 16)
189720dd621STang Haojin            case _: String => BigInt(value)
190720dd621STang Haojin          }
191720dd621STang Haojin          nextOption(tail)
192720dd621STang Haojin        case "--device-addr-width" :: value :: tail =>
193720dd621STang Haojin          addrWidth = value.toInt
194720dd621STang Haojin          nextOption(tail)
195720dd621STang Haojin        case "--device-data-width" :: value :: tail =>
196720dd621STang Haojin          dataWidth = value.toInt
197720dd621STang Haojin          nextOption(tail)
198720dd621STang Haojin        case option :: tail =>
199720dd621STang Haojin          // unknown option, maybe a firrtl option, skip
200720dd621STang Haojin          firrtlOpts :+= option
201720dd621STang Haojin          nextOption(tail)
202720dd621STang Haojin      }
203720dd621STang Haojin    }
204720dd621STang Haojin    nextOption(args.toList)
205720dd621STang Haojin    require(baseAddress >= 0, "baseAddress not specified correctly")
206720dd621STang Haojin    require(addrWidth >= 0, "addrWidth not specified correctly")
207720dd621STang Haojin    require(dataWidth >= 0, "dataWidth not specified correctly")
208720dd621STang Haojin    val device: StandAloneDevice = module match {
209720dd621STang Haojin      case "StandAloneCLINT" =>
210720dd621STang Haojin        DisableMonitors(p => LazyModule(new StandAloneCLINT(
211720dd621STang Haojin          useTL, baseAddress, addrWidth, dataWidth, p(XSTileKey).size
212720dd621STang Haojin        )(p)))(p)
213720dd621STang Haojin      case "StandAlonePLIC" =>
214720dd621STang Haojin        DisableMonitors(p => LazyModule(new StandAlonePLIC(
215720dd621STang Haojin          useTL, baseAddress, addrWidth, dataWidth, p(XSTileKey).size
216720dd621STang Haojin        )(p)))(p)
217720dd621STang Haojin      case "StandAloneDebugModule" =>
218720dd621STang Haojin        DisableMonitors(p => LazyModule(new StandAloneDebugModule(
219720dd621STang Haojin          useTL, baseAddress, addrWidth, dataWidth, p(XSTileKey).size
220720dd621STang Haojin        )(p)))(p)
221720dd621STang Haojin      case _: String => throw new IllegalArgumentException(s"$module not found")
222720dd621STang Haojin    }
223720dd621STang Haojin    (device, firrtlOpts)
224720dd621STang Haojin  }
225720dd621STang Haojin}
226720dd621STang Haojin
227720dd621STang Haojinobject Main extends App {
228720dd621STang Haojin  val (config, secondaryOpts, firtoolOpts) = top.ArgParser.parse(args)
229720dd621STang Haojin  val (device, firrtlOpts) = ArgParser.parse(secondaryOpts, config)
230720dd621STang Haojin
231720dd621STang Haojin  Generator.execute(firrtlOpts, device.module, firtoolOpts)
232720dd621STang Haojin}
233