xref: /XiangShan/src/main/scala/device/standalone/StandAloneDevice.scala (revision 720dd6218ef4045360a23b552db1137cbb6e6e59)
1*720dd621STang Haojin/***************************************************************************************
2*720dd621STang Haojin* Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences
3*720dd621STang Haojin* Copyright (c) 2020-2021 Peng Cheng Laboratory
4*720dd621STang Haojin*
5*720dd621STang Haojin* XiangShan is licensed under Mulan PSL v2.
6*720dd621STang Haojin* You can use this software according to the terms and conditions of the Mulan PSL v2.
7*720dd621STang Haojin* You may obtain a copy of Mulan PSL v2 at:
8*720dd621STang Haojin*          http://license.coscl.org.cn/MulanPSL2
9*720dd621STang Haojin*
10*720dd621STang Haojin* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
11*720dd621STang Haojin* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
12*720dd621STang Haojin* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
13*720dd621STang Haojin*
14*720dd621STang Haojin* See the Mulan PSL v2 for more details.
15*720dd621STang Haojin***************************************************************************************/
16*720dd621STang Haojin
17*720dd621STang Haojinpackage device.standalone
18*720dd621STang Haojin
19*720dd621STang Haojinimport chisel3._
20*720dd621STang Haojinimport chisel3.util._
21*720dd621STang Haojinimport chisel3.experimental._
22*720dd621STang Haojinimport freechips.rocketchip.diplomacy._
23*720dd621STang Haojinimport org.chipsalliance.cde.config.Parameters
24*720dd621STang Haojinimport freechips.rocketchip.devices.tilelink._
25*720dd621STang Haojinimport freechips.rocketchip.amba.axi4._
26*720dd621STang Haojinimport freechips.rocketchip.tilelink._
27*720dd621STang Haojinimport top.Generator
28*720dd621STang Haojinimport system.SoCParamsKey
29*720dd621STang Haojinimport sifive.enterprise.firrtl.NestedPrefixModulesAnnotation
30*720dd621STang Haojinimport scala.annotation.tailrec
31*720dd621STang Haojinimport xiangshan.XSTileKey
32*720dd621STang Haojin
33*720dd621STang Haojintrait HasMasterInterface { this: StandAloneDevice =>
34*720dd621STang Haojin
35*720dd621STang Haojin  protected val masternode = TLIdentityNode()
36*720dd621STang Haojin  // tilelink master io
37*720dd621STang Haojin  private val tlmaster = Option.when(useTL)(TLManagerNode(Seq(
38*720dd621STang Haojin    TLSlavePortParameters.v1(
39*720dd621STang Haojin      managers = Seq(
40*720dd621STang Haojin        TLSlaveParameters.v1(
41*720dd621STang Haojin          address = Seq(AddressSet(0, (BigInt(1) << addrWidth) - 1)),
42*720dd621STang Haojin          regionType = RegionType.UNCACHED,
43*720dd621STang Haojin          supportsGet = TransferSizes(1, p(SoCParamsKey).L3BlockSize),
44*720dd621STang Haojin          supportsPutPartial = TransferSizes(1, p(SoCParamsKey).L3BlockSize),
45*720dd621STang Haojin          supportsPutFull = TransferSizes(1, p(SoCParamsKey).L3BlockSize),
46*720dd621STang Haojin          fifoId = Some(0)
47*720dd621STang Haojin        )
48*720dd621STang Haojin      ),
49*720dd621STang Haojin      beatBytes = p(SoCParamsKey).L3OuterBusWidth / 8
50*720dd621STang Haojin    )
51*720dd621STang Haojin  )))
52*720dd621STang Haojin  tlmaster.foreach(_ := masternode)
53*720dd621STang Haojin  val tlmasternode = tlmaster.map(tlmaster => InModuleBody(tlmaster.makeIOs()))
54*720dd621STang Haojin
55*720dd621STang Haojin  // axi4 master io
56*720dd621STang Haojin  private val axi4master = Option.when(!useTL)(AXI4SlaveNode(Seq(
57*720dd621STang Haojin    AXI4SlavePortParameters(
58*720dd621STang Haojin      slaves = Seq(
59*720dd621STang Haojin        AXI4SlaveParameters(
60*720dd621STang Haojin          address = Seq(AddressSet(0, (BigInt(1) << addrWidth) - 1)),
61*720dd621STang Haojin          regionType = RegionType.UNCACHED,
62*720dd621STang Haojin          supportsRead = TransferSizes(1, p(SoCParamsKey).L3BlockSize),
63*720dd621STang Haojin          supportsWrite = TransferSizes(1, p(SoCParamsKey).L3BlockSize),
64*720dd621STang Haojin          interleavedId = Some(0)
65*720dd621STang Haojin        )
66*720dd621STang Haojin      ),
67*720dd621STang Haojin      beatBytes = p(SoCParamsKey).L3OuterBusWidth / 8
68*720dd621STang Haojin    )
69*720dd621STang Haojin  )))
70*720dd621STang Haojin  axi4master.foreach(
71*720dd621STang Haojin    _ :=
72*720dd621STang Haojin      AXI4Buffer() :=
73*720dd621STang Haojin      AXI4Buffer() :=
74*720dd621STang Haojin      AXI4Buffer() :=
75*720dd621STang Haojin      AXI4IdIndexer(1) :=
76*720dd621STang Haojin      AXI4UserYanker() :=
77*720dd621STang Haojin      AXI4Deinterleaver(p(SoCParamsKey).L3BlockSize) :=
78*720dd621STang Haojin      TLToAXI4() :=
79*720dd621STang Haojin      TLSourceShrinker(64) :=
80*720dd621STang Haojin      TLWidthWidget(p(SoCParamsKey).L3OuterBusWidth / 8) :=
81*720dd621STang Haojin      TLBuffer.chainNode(2) :=
82*720dd621STang Haojin      masternode
83*720dd621STang Haojin  )
84*720dd621STang Haojin  val axi4masternode = axi4master.map(axi4master => InModuleBody(axi4master.makeIOs()))
85*720dd621STang Haojin}
86*720dd621STang Haojin
87*720dd621STang Haojinabstract class StandAloneDevice (
88*720dd621STang Haojin  val useTL: Boolean = false,
89*720dd621STang Haojin  val baseAddress: BigInt,
90*720dd621STang Haojin  val addrWidth: Int,
91*720dd621STang Haojin  val dataWidth: Int,
92*720dd621STang Haojin  val hartNum: Int
93*720dd621STang Haojin)(implicit p: Parameters) extends LazyModule {
94*720dd621STang Haojin
95*720dd621STang Haojin  def addressSet: AddressSet
96*720dd621STang Haojin
97*720dd621STang Haojin  private val dummy = LazyModule(new TLError(
98*720dd621STang Haojin    params = DevNullParams(
99*720dd621STang Haojin      address = AddressSet(0, (BigInt(1) << addrWidth) - 1).subtract(addressSet),
100*720dd621STang Haojin      maxAtomic = 8,
101*720dd621STang Haojin      maxTransfer = 64
102*720dd621STang Haojin    ),
103*720dd621STang Haojin    beatBytes = dataWidth / 8
104*720dd621STang Haojin  ))
105*720dd621STang Haojin  protected val xbar = TLXbar()
106*720dd621STang Haojin  dummy.node := xbar
107*720dd621STang Haojin
108*720dd621STang Haojin  // tilelink io
109*720dd621STang Haojin  private val tl = Option.when(useTL)(TLClientNode(Seq(TLMasterPortParameters.v1(
110*720dd621STang Haojin    Seq(TLMasterParameters.v1("tl", IdRange(0, 1)))
111*720dd621STang Haojin  ))))
112*720dd621STang Haojin  tl.foreach(xbar := _)
113*720dd621STang Haojin  val tlnode = tl.map(tl => InModuleBody(tl.makeIOs()))
114*720dd621STang Haojin
115*720dd621STang Haojin  // axi4 io
116*720dd621STang Haojin  private val axi4 = Option.when(!useTL)(AXI4MasterNode(Seq(AXI4MasterPortParameters(
117*720dd621STang Haojin    Seq(AXI4MasterParameters("axi4", IdRange(0, 1)))
118*720dd621STang Haojin  ))))
119*720dd621STang Haojin  axi4.foreach(
120*720dd621STang Haojin    xbar :=
121*720dd621STang Haojin      TLFIFOFixer() :=
122*720dd621STang Haojin      AXI4ToTL() :=
123*720dd621STang Haojin      AXI4UserYanker(Some(1)) :=
124*720dd621STang Haojin      AXI4Fragmenter() :=
125*720dd621STang Haojin      AXI4Buffer() :=
126*720dd621STang Haojin      AXI4Buffer() :=
127*720dd621STang Haojin      AXI4IdIndexer(1) :=
128*720dd621STang Haojin      _
129*720dd621STang Haojin  )
130*720dd621STang Haojin  val axi4node = axi4.map(axi4 => InModuleBody(axi4.makeIOs()))
131*720dd621STang Haojin
132*720dd621STang Haojin  lazy val module: StandAloneDeviceImp = new StandAloneDeviceImp(this)
133*720dd621STang Haojin
134*720dd621STang Haojin}
135*720dd621STang Haojin
136*720dd621STang Haojinclass StandAloneDeviceImp(outer: StandAloneDevice)(implicit p: Parameters) extends LazyModuleImp(outer) {
137*720dd621STang Haojin  p(SoCParamsKey).XSTopPrefix.foreach { prefix =>
138*720dd621STang Haojin    val mod = this.toNamed
139*720dd621STang Haojin    annotate(new ChiselAnnotation {
140*720dd621STang Haojin      def toFirrtl = NestedPrefixModulesAnnotation(mod, prefix, true)
141*720dd621STang Haojin    })
142*720dd621STang Haojin  }
143*720dd621STang Haojin}
144*720dd621STang Haojin
145*720dd621STang Haojinobject ArgParser {
146*720dd621STang Haojin  def parse(args: Array[String], p: Parameters): (StandAloneDevice, Array[String]) = {
147*720dd621STang Haojin    var firrtlOpts = Array[String]()
148*720dd621STang Haojin    var module: String = ""
149*720dd621STang Haojin    var useTL: Boolean = false
150*720dd621STang Haojin    var baseAddress: BigInt = -1
151*720dd621STang Haojin    var addrWidth: Int = -1
152*720dd621STang Haojin    var dataWidth: Int = 64
153*720dd621STang Haojin    @tailrec
154*720dd621STang Haojin    def nextOption(list: List[String]): Unit = {
155*720dd621STang Haojin      list match {
156*720dd621STang Haojin        case Nil =>
157*720dd621STang Haojin        case "--standalone-device" :: value :: tail =>
158*720dd621STang Haojin          module = value
159*720dd621STang Haojin          nextOption(tail)
160*720dd621STang Haojin        case "--use-tl" :: tail =>
161*720dd621STang Haojin          useTL = true
162*720dd621STang Haojin          nextOption(tail)
163*720dd621STang Haojin        case "--use-axi4" :: tail =>
164*720dd621STang Haojin          useTL = false
165*720dd621STang Haojin          nextOption(tail)
166*720dd621STang Haojin        case "--device-base-addr" :: value :: tail =>
167*720dd621STang Haojin          baseAddress = value match {
168*720dd621STang Haojin            case s"0x$hex" => BigInt(hex, 16)
169*720dd621STang Haojin            case s"0X$hex" => BigInt(hex, 16)
170*720dd621STang Haojin            case _: String => BigInt(value)
171*720dd621STang Haojin          }
172*720dd621STang Haojin          nextOption(tail)
173*720dd621STang Haojin        case "--device-addr-width" :: value :: tail =>
174*720dd621STang Haojin          addrWidth = value.toInt
175*720dd621STang Haojin          nextOption(tail)
176*720dd621STang Haojin        case "--device-data-width" :: value :: tail =>
177*720dd621STang Haojin          dataWidth = value.toInt
178*720dd621STang Haojin          nextOption(tail)
179*720dd621STang Haojin        case option :: tail =>
180*720dd621STang Haojin          // unknown option, maybe a firrtl option, skip
181*720dd621STang Haojin          firrtlOpts :+= option
182*720dd621STang Haojin          nextOption(tail)
183*720dd621STang Haojin      }
184*720dd621STang Haojin    }
185*720dd621STang Haojin    nextOption(args.toList)
186*720dd621STang Haojin    require(baseAddress >= 0, "baseAddress not specified correctly")
187*720dd621STang Haojin    require(addrWidth >= 0, "addrWidth not specified correctly")
188*720dd621STang Haojin    require(dataWidth >= 0, "dataWidth not specified correctly")
189*720dd621STang Haojin    val device: StandAloneDevice = module match {
190*720dd621STang Haojin      case "StandAloneCLINT" =>
191*720dd621STang Haojin        DisableMonitors(p => LazyModule(new StandAloneCLINT(
192*720dd621STang Haojin          useTL, baseAddress, addrWidth, dataWidth, p(XSTileKey).size
193*720dd621STang Haojin        )(p)))(p)
194*720dd621STang Haojin      case "StandAlonePLIC" =>
195*720dd621STang Haojin        DisableMonitors(p => LazyModule(new StandAlonePLIC(
196*720dd621STang Haojin          useTL, baseAddress, addrWidth, dataWidth, p(XSTileKey).size
197*720dd621STang Haojin        )(p)))(p)
198*720dd621STang Haojin      case "StandAloneDebugModule" =>
199*720dd621STang Haojin        DisableMonitors(p => LazyModule(new StandAloneDebugModule(
200*720dd621STang Haojin          useTL, baseAddress, addrWidth, dataWidth, p(XSTileKey).size
201*720dd621STang Haojin        )(p)))(p)
202*720dd621STang Haojin      case _: String => throw new IllegalArgumentException(s"$module not found")
203*720dd621STang Haojin    }
204*720dd621STang Haojin    (device, firrtlOpts)
205*720dd621STang Haojin  }
206*720dd621STang Haojin}
207*720dd621STang Haojin
208*720dd621STang Haojinobject Main extends App {
209*720dd621STang Haojin  val (config, secondaryOpts, firtoolOpts) = top.ArgParser.parse(args)
210*720dd621STang Haojin  val (device, firrtlOpts) = ArgParser.parse(secondaryOpts, config)
211*720dd621STang Haojin
212*720dd621STang Haojin  Generator.execute(firrtlOpts, device.module, firtoolOpts)
213*720dd621STang Haojin}
214