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 25aef22314STang Haojinimport freechips.rocketchip.devices.debug.DebugModuleKey 26720dd621STang Haojinimport freechips.rocketchip.devices.tilelink._ 27720dd621STang Haojinimport freechips.rocketchip.amba.axi4._ 28720dd621STang Haojinimport freechips.rocketchip.tilelink._ 29720dd621STang Haojinimport top.Generator 30720dd621STang Haojinimport system.SoCParamsKey 31720dd621STang Haojinimport sifive.enterprise.firrtl.NestedPrefixModulesAnnotation 32720dd621STang Haojinimport scala.annotation.tailrec 33720dd621STang Haojinimport xiangshan.XSTileKey 344391123aSTang Haojinimport utils.VerilogAXI4Record 35720dd621STang Haojin 36720dd621STang Haojintrait HasMasterInterface { this: StandAloneDevice => 37720dd621STang Haojin 38*4adf8eb8STang Haojin def masterAddrWidth: Int 39*4adf8eb8STang Haojin 40720dd621STang Haojin protected val masternode = TLIdentityNode() 41720dd621STang Haojin // tilelink master io 42720dd621STang Haojin private val tlmaster = Option.when(useTL)(TLManagerNode(Seq( 43720dd621STang Haojin TLSlavePortParameters.v1( 44720dd621STang Haojin managers = Seq( 45720dd621STang Haojin TLSlaveParameters.v1( 46*4adf8eb8STang Haojin address = Seq(AddressSet(0, (BigInt(1) << masterAddrWidth) - 1)), 47720dd621STang Haojin regionType = RegionType.UNCACHED, 48720dd621STang Haojin supportsGet = TransferSizes(1, p(SoCParamsKey).L3BlockSize), 49720dd621STang Haojin supportsPutPartial = TransferSizes(1, p(SoCParamsKey).L3BlockSize), 50720dd621STang Haojin supportsPutFull = TransferSizes(1, p(SoCParamsKey).L3BlockSize), 51720dd621STang Haojin fifoId = Some(0) 52720dd621STang Haojin ) 53720dd621STang Haojin ), 54720dd621STang Haojin beatBytes = p(SoCParamsKey).L3OuterBusWidth / 8 55720dd621STang Haojin ) 56720dd621STang Haojin ))) 57720dd621STang Haojin tlmaster.foreach(_ := masternode) 58720dd621STang Haojin val tlmasternode = tlmaster.map(tlmaster => InModuleBody(tlmaster.makeIOs())) 59720dd621STang Haojin 60720dd621STang Haojin // axi4 master io 61720dd621STang Haojin private val axi4master = Option.when(!useTL)(AXI4SlaveNode(Seq( 62720dd621STang Haojin AXI4SlavePortParameters( 63720dd621STang Haojin slaves = Seq( 64720dd621STang Haojin AXI4SlaveParameters( 65*4adf8eb8STang Haojin address = Seq(AddressSet(0, (BigInt(1) << masterAddrWidth) - 1)), 66720dd621STang Haojin regionType = RegionType.UNCACHED, 67720dd621STang Haojin supportsRead = TransferSizes(1, p(SoCParamsKey).L3BlockSize), 68720dd621STang Haojin supportsWrite = TransferSizes(1, p(SoCParamsKey).L3BlockSize), 69720dd621STang Haojin interleavedId = Some(0) 70720dd621STang Haojin ) 71720dd621STang Haojin ), 72720dd621STang Haojin beatBytes = p(SoCParamsKey).L3OuterBusWidth / 8 73720dd621STang Haojin ) 74720dd621STang Haojin ))) 75720dd621STang Haojin axi4master.foreach( 76720dd621STang Haojin _ := 77720dd621STang Haojin AXI4Buffer() := 78720dd621STang Haojin AXI4Buffer() := 79720dd621STang Haojin AXI4Buffer() := 80720dd621STang Haojin AXI4IdIndexer(1) := 81720dd621STang Haojin AXI4UserYanker() := 82720dd621STang Haojin AXI4Deinterleaver(p(SoCParamsKey).L3BlockSize) := 83720dd621STang Haojin TLToAXI4() := 84720dd621STang Haojin TLSourceShrinker(64) := 85720dd621STang Haojin TLWidthWidget(p(SoCParamsKey).L3OuterBusWidth / 8) := 86720dd621STang Haojin TLBuffer.chainNode(2) := 87720dd621STang Haojin masternode 88720dd621STang Haojin ) 894391123aSTang Haojin val axi4masternode = axi4master.map(axi4master => InModuleBody { 90bb2f3f51STang Haojin val axi4masternode = chisel3.IO(new VerilogAXI4Record(axi4master.in.head._1.params)) 914391123aSTang Haojin axi4masternode.viewAs[AXI4Bundle] <> axi4master.in.head._1 924391123aSTang Haojin axi4masternode 934391123aSTang Haojin }) 94720dd621STang Haojin} 95720dd621STang Haojin 96720dd621STang Haojinabstract class StandAloneDevice ( 97720dd621STang Haojin val useTL: Boolean = false, 98720dd621STang Haojin val baseAddress: BigInt, 99720dd621STang Haojin val addrWidth: Int, 100720dd621STang Haojin val dataWidth: Int, 101720dd621STang Haojin val hartNum: Int 102720dd621STang Haojin)(implicit p: Parameters) extends LazyModule { 103720dd621STang Haojin 104720dd621STang Haojin def addressSet: AddressSet 105720dd621STang Haojin 106720dd621STang Haojin private val dummy = LazyModule(new TLError( 107720dd621STang Haojin params = DevNullParams( 108720dd621STang Haojin address = AddressSet(0, (BigInt(1) << addrWidth) - 1).subtract(addressSet), 109720dd621STang Haojin maxAtomic = 8, 110720dd621STang Haojin maxTransfer = 64 111720dd621STang Haojin ), 112720dd621STang Haojin beatBytes = dataWidth / 8 113720dd621STang Haojin )) 114720dd621STang Haojin protected val xbar = TLXbar() 115720dd621STang Haojin dummy.node := xbar 116720dd621STang Haojin 117720dd621STang Haojin // tilelink io 118720dd621STang Haojin private val tl = Option.when(useTL)(TLClientNode(Seq(TLMasterPortParameters.v1( 119720dd621STang Haojin Seq(TLMasterParameters.v1("tl", IdRange(0, 1))) 120720dd621STang Haojin )))) 121720dd621STang Haojin tl.foreach(xbar := _) 122720dd621STang Haojin val tlnode = tl.map(tl => InModuleBody(tl.makeIOs())) 123720dd621STang Haojin 124720dd621STang Haojin // axi4 io 125720dd621STang Haojin private val axi4 = Option.when(!useTL)(AXI4MasterNode(Seq(AXI4MasterPortParameters( 126720dd621STang Haojin Seq(AXI4MasterParameters("axi4", IdRange(0, 1))) 127720dd621STang Haojin )))) 128720dd621STang Haojin axi4.foreach( 129720dd621STang Haojin xbar := 130720dd621STang Haojin TLFIFOFixer() := 131720dd621STang Haojin AXI4ToTL() := 132720dd621STang Haojin AXI4UserYanker(Some(1)) := 133720dd621STang Haojin AXI4Fragmenter() := 134720dd621STang Haojin AXI4Buffer() := 135720dd621STang Haojin AXI4Buffer() := 136720dd621STang Haojin AXI4IdIndexer(1) := 137720dd621STang Haojin _ 138720dd621STang Haojin ) 1394391123aSTang Haojin val axi4node = axi4.map(axi4 => InModuleBody { 140bb2f3f51STang Haojin val axi4node = chisel3.IO(Flipped(new VerilogAXI4Record(axi4.out.head._1.params))) 1414391123aSTang Haojin axi4node.viewAs[AXI4Bundle] <> axi4.out.head._1 1424391123aSTang Haojin axi4node 1434391123aSTang Haojin }) 144720dd621STang Haojin 145b6ace320STang Haojin lazy val module: LazyModuleImpLike = new StandAloneDeviceImp(this) 146720dd621STang Haojin 147720dd621STang Haojin} 148720dd621STang Haojin 14930e7906fSHaojin Tangclass StandAloneDeviceImp(outer: StandAloneDevice)(implicit p: Parameters) extends LazyModuleImp(outer) with RequireAsyncReset { 150720dd621STang Haojin p(SoCParamsKey).XSTopPrefix.foreach { prefix => 151720dd621STang Haojin val mod = this.toNamed 152720dd621STang Haojin annotate(new ChiselAnnotation { 153720dd621STang Haojin def toFirrtl = NestedPrefixModulesAnnotation(mod, prefix, true) 154720dd621STang Haojin }) 155720dd621STang Haojin } 156720dd621STang Haojin} 157720dd621STang Haojin 158b6ace320STang Haojinclass StandAloneDeviceRawImp(outer: StandAloneDevice)(implicit p: Parameters) extends LazyRawModuleImp(outer) { 159b6ace320STang Haojin p(SoCParamsKey).XSTopPrefix.foreach { prefix => 160b6ace320STang Haojin val mod = this.toNamed 161b6ace320STang Haojin annotate(new ChiselAnnotation { 162b6ace320STang Haojin def toFirrtl = NestedPrefixModulesAnnotation(mod, prefix, true) 163b6ace320STang Haojin }) 164b6ace320STang Haojin } 165b6ace320STang Haojin} 166b6ace320STang Haojin 167720dd621STang Haojinobject ArgParser { 168720dd621STang Haojin def parse(args: Array[String], p: Parameters): (StandAloneDevice, Array[String]) = { 169720dd621STang Haojin var firrtlOpts = Array[String]() 170720dd621STang Haojin var module: String = "" 171720dd621STang Haojin var useTL: Boolean = false 172720dd621STang Haojin var baseAddress: BigInt = -1 173720dd621STang Haojin var addrWidth: Int = -1 174720dd621STang Haojin var dataWidth: Int = 64 175720dd621STang Haojin @tailrec 176720dd621STang Haojin def nextOption(list: List[String]): Unit = { 177720dd621STang Haojin list match { 178720dd621STang Haojin case Nil => 179720dd621STang Haojin case "--standalone-device" :: value :: tail => 180720dd621STang Haojin module = value 181720dd621STang Haojin nextOption(tail) 182720dd621STang Haojin case "--use-tl" :: tail => 183720dd621STang Haojin useTL = true 184720dd621STang Haojin nextOption(tail) 185720dd621STang Haojin case "--use-axi4" :: tail => 186720dd621STang Haojin useTL = false 187720dd621STang Haojin nextOption(tail) 188720dd621STang Haojin case "--device-base-addr" :: value :: tail => 189720dd621STang Haojin baseAddress = value match { 190720dd621STang Haojin case s"0x$hex" => BigInt(hex, 16) 191720dd621STang Haojin case s"0X$hex" => BigInt(hex, 16) 192720dd621STang Haojin case _: String => BigInt(value) 193720dd621STang Haojin } 194720dd621STang Haojin nextOption(tail) 195720dd621STang Haojin case "--device-addr-width" :: value :: tail => 196720dd621STang Haojin addrWidth = value.toInt 197720dd621STang Haojin nextOption(tail) 198720dd621STang Haojin case "--device-data-width" :: value :: tail => 199720dd621STang Haojin dataWidth = value.toInt 200720dd621STang Haojin nextOption(tail) 201720dd621STang Haojin case option :: tail => 202720dd621STang Haojin // unknown option, maybe a firrtl option, skip 203720dd621STang Haojin firrtlOpts :+= option 204720dd621STang Haojin nextOption(tail) 205720dd621STang Haojin } 206720dd621STang Haojin } 207720dd621STang Haojin nextOption(args.toList) 208720dd621STang Haojin require(baseAddress >= 0, "baseAddress not specified correctly") 209720dd621STang Haojin require(addrWidth >= 0, "addrWidth not specified correctly") 210720dd621STang Haojin require(dataWidth >= 0, "dataWidth not specified correctly") 211720dd621STang Haojin val device: StandAloneDevice = module match { 212720dd621STang Haojin case "StandAloneCLINT" => 213720dd621STang Haojin DisableMonitors(p => LazyModule(new StandAloneCLINT( 214720dd621STang Haojin useTL, baseAddress, addrWidth, dataWidth, p(XSTileKey).size 215720dd621STang Haojin )(p)))(p) 216720dd621STang Haojin case "StandAlonePLIC" => 217720dd621STang Haojin DisableMonitors(p => LazyModule(new StandAlonePLIC( 218720dd621STang Haojin useTL, baseAddress, addrWidth, dataWidth, p(XSTileKey).size 219720dd621STang Haojin )(p)))(p) 220720dd621STang Haojin case "StandAloneDebugModule" => 221720dd621STang Haojin DisableMonitors(p => LazyModule(new StandAloneDebugModule( 222720dd621STang Haojin useTL, baseAddress, addrWidth, dataWidth, p(XSTileKey).size 223aef22314STang Haojin )(p)))(p.alter((site, here, up) => { 224aef22314STang Haojin case DebugModuleKey => up(DebugModuleKey).map(_.copy(baseAddress = baseAddress)) 225aef22314STang Haojin })) 226720dd621STang Haojin case _: String => throw new IllegalArgumentException(s"$module not found") 227720dd621STang Haojin } 228720dd621STang Haojin (device, firrtlOpts) 229720dd621STang Haojin } 230720dd621STang Haojin} 231720dd621STang Haojin 232720dd621STang Haojinobject Main extends App { 233720dd621STang Haojin val (config, secondaryOpts, firtoolOpts) = top.ArgParser.parse(args) 234720dd621STang Haojin val (device, firrtlOpts) = ArgParser.parse(secondaryOpts, config) 235720dd621STang Haojin 236720dd621STang Haojin Generator.execute(firrtlOpts, device.module, firtoolOpts) 237720dd621STang Haojin} 238