xref: /XiangShan/src/main/scala/device/standalone/StandAloneDevice.scala (revision b64156d0f3d785688ca08fae76b70bd060f7f441)
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._
21*b64156d0Ssinsanctionimport 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 {
874391123aSTang Haojin    val axi4masternode = 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 {
1374391123aSTang Haojin    val axi4node = 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
142720dd621STang Haojin  lazy val module: StandAloneDeviceImp = new StandAloneDeviceImp(this)
143720dd621STang Haojin
144720dd621STang Haojin}
145720dd621STang Haojin
146720dd621STang Haojinclass StandAloneDeviceImp(outer: StandAloneDevice)(implicit p: Parameters) extends LazyModuleImp(outer) {
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
155720dd621STang Haojinobject ArgParser {
156720dd621STang Haojin  def parse(args: Array[String], p: Parameters): (StandAloneDevice, Array[String]) = {
157720dd621STang Haojin    var firrtlOpts = Array[String]()
158720dd621STang Haojin    var module: String = ""
159720dd621STang Haojin    var useTL: Boolean = false
160720dd621STang Haojin    var baseAddress: BigInt = -1
161720dd621STang Haojin    var addrWidth: Int = -1
162720dd621STang Haojin    var dataWidth: Int = 64
163720dd621STang Haojin    @tailrec
164720dd621STang Haojin    def nextOption(list: List[String]): Unit = {
165720dd621STang Haojin      list match {
166720dd621STang Haojin        case Nil =>
167720dd621STang Haojin        case "--standalone-device" :: value :: tail =>
168720dd621STang Haojin          module = value
169720dd621STang Haojin          nextOption(tail)
170720dd621STang Haojin        case "--use-tl" :: tail =>
171720dd621STang Haojin          useTL = true
172720dd621STang Haojin          nextOption(tail)
173720dd621STang Haojin        case "--use-axi4" :: tail =>
174720dd621STang Haojin          useTL = false
175720dd621STang Haojin          nextOption(tail)
176720dd621STang Haojin        case "--device-base-addr" :: value :: tail =>
177720dd621STang Haojin          baseAddress = value match {
178720dd621STang Haojin            case s"0x$hex" => BigInt(hex, 16)
179720dd621STang Haojin            case s"0X$hex" => BigInt(hex, 16)
180720dd621STang Haojin            case _: String => BigInt(value)
181720dd621STang Haojin          }
182720dd621STang Haojin          nextOption(tail)
183720dd621STang Haojin        case "--device-addr-width" :: value :: tail =>
184720dd621STang Haojin          addrWidth = value.toInt
185720dd621STang Haojin          nextOption(tail)
186720dd621STang Haojin        case "--device-data-width" :: value :: tail =>
187720dd621STang Haojin          dataWidth = value.toInt
188720dd621STang Haojin          nextOption(tail)
189720dd621STang Haojin        case option :: tail =>
190720dd621STang Haojin          // unknown option, maybe a firrtl option, skip
191720dd621STang Haojin          firrtlOpts :+= option
192720dd621STang Haojin          nextOption(tail)
193720dd621STang Haojin      }
194720dd621STang Haojin    }
195720dd621STang Haojin    nextOption(args.toList)
196720dd621STang Haojin    require(baseAddress >= 0, "baseAddress not specified correctly")
197720dd621STang Haojin    require(addrWidth >= 0, "addrWidth not specified correctly")
198720dd621STang Haojin    require(dataWidth >= 0, "dataWidth not specified correctly")
199720dd621STang Haojin    val device: StandAloneDevice = module match {
200720dd621STang Haojin      case "StandAloneCLINT" =>
201720dd621STang Haojin        DisableMonitors(p => LazyModule(new StandAloneCLINT(
202720dd621STang Haojin          useTL, baseAddress, addrWidth, dataWidth, p(XSTileKey).size
203720dd621STang Haojin        )(p)))(p)
204720dd621STang Haojin      case "StandAlonePLIC" =>
205720dd621STang Haojin        DisableMonitors(p => LazyModule(new StandAlonePLIC(
206720dd621STang Haojin          useTL, baseAddress, addrWidth, dataWidth, p(XSTileKey).size
207720dd621STang Haojin        )(p)))(p)
208720dd621STang Haojin      case "StandAloneDebugModule" =>
209720dd621STang Haojin        DisableMonitors(p => LazyModule(new StandAloneDebugModule(
210720dd621STang Haojin          useTL, baseAddress, addrWidth, dataWidth, p(XSTileKey).size
211720dd621STang Haojin        )(p)))(p)
212720dd621STang Haojin      case _: String => throw new IllegalArgumentException(s"$module not found")
213720dd621STang Haojin    }
214720dd621STang Haojin    (device, firrtlOpts)
215720dd621STang Haojin  }
216720dd621STang Haojin}
217720dd621STang Haojin
218720dd621STang Haojinobject Main extends App {
219720dd621STang Haojin  val (config, secondaryOpts, firtoolOpts) = top.ArgParser.parse(args)
220720dd621STang Haojin  val (device, firrtlOpts) = ArgParser.parse(secondaryOpts, config)
221720dd621STang Haojin
222720dd621STang Haojin  Generator.execute(firrtlOpts, device.module, firtoolOpts)
223720dd621STang Haojin}
224