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