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