1/*************************************************************************************** 2* Copyright (c) 2024 Beijing Institute of Open Source Chip (BOSC) 3* Copyright (c) 2020-2024 Institute of Computing Technology, Chinese Academy of Sciences 4* Copyright (c) 2020-2021 Peng Cheng Laboratory 5* 6* XiangShan is licensed under Mulan PSL v2. 7* You can use this software according to the terms and conditions of the Mulan PSL v2. 8* You may obtain a copy of Mulan PSL v2 at: 9* http://license.coscl.org.cn/MulanPSL2 10* 11* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, 12* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, 13* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. 14* 15* See the Mulan PSL v2 for more details. 16***************************************************************************************/ 17 18package top 19 20import org.chipsalliance.cde.config.{Config, Parameters} 21import system.SoCParamsKey 22import xiangshan.{DebugOptionsKey, XSTileKey} 23import freechips.rocketchip.tile.MaxHartIdBits 24import difftest.DifftestModule 25 26import scala.annotation.tailrec 27import scala.sys.exit 28import chisel3.util.log2Up 29import utility._ 30import device.IMSICBusType 31 32object ArgParser { 33 // TODO: add more explainations 34 val usage = 35 """ 36 |XiangShan Options 37 |--xs-help print this help message 38 |--version print version info 39 |--config <ConfigClassName> 40 |--num-cores <Int> 41 |--hartidbits <Int> 42 |--with-dramsim3 43 |--fpga-platform 44 |--reset-gen 45 |--enable-difftest 46 |--enable-log 47 |--with-chiseldb 48 |--with-rollingdb 49 |--disable-perf 50 |--disable-alwaysdb 51 |--enable-dfx 52 |""".stripMargin 53 54 def getConfigByName(confString: String): Parameters = { 55 var prefix = "top." // default package is 'top' 56 if(confString.contains('.')){ // already a full name 57 prefix = "" 58 } 59 val c = Class.forName(prefix + confString).getConstructor(Integer.TYPE) 60 c.newInstance(1.asInstanceOf[Object]).asInstanceOf[Parameters] 61 } 62 def parse(args: Array[String]): (Parameters, Array[String], Array[String]) = { 63 val default = new DefaultConfig(1) 64 var firrtlOpts = Array[String]() 65 var firtoolOpts = Array[String]() 66 @tailrec 67 def nextOption(config: Parameters, list: List[String]): Parameters = { 68 list match { 69 case Nil => config 70 case "--xs-help" :: tail => 71 println(usage) 72 if(tail == Nil) exit(0) 73 nextOption(config, tail) 74 case "--version" :: tail => 75 println(os.read(os.resource / "publishVersion")) 76 if(tail == Nil) exit(0) 77 nextOption(config, tail) 78 case "--config" :: confString :: tail => 79 nextOption(getConfigByName(confString), tail) 80 case "--issue" :: issueString :: tail => 81 nextOption(config.alter((site, here, up) => { 82 case coupledL2.tl2chi.CHIIssue => issueString 83 }), tail) 84 case "--num-cores" :: value :: tail => 85 nextOption(config.alter((site, here, up) => { 86 case XSTileKey => (0 until value.toInt) map { i => 87 up(XSTileKey).head.copy(HartId = i) 88 } 89 case MaxHartIdBits => 90 log2Up(value.toInt) max up(MaxHartIdBits) 91 }), tail) 92 case "--hartidbits" :: hartidbits :: tail => 93 nextOption(config.alter((site, here, up) => { 94 case MaxHartIdBits => hartidbits 95 }), tail) 96 case "--with-dramsim3" :: tail => 97 nextOption(config.alter((site, here, up) => { 98 case DebugOptionsKey => up(DebugOptionsKey).copy(UseDRAMSim = true) 99 }), tail) 100 case "--with-chiseldb" :: tail => 101 nextOption(config.alter((site, here, up) => { 102 case DebugOptionsKey => up(DebugOptionsKey).copy(EnableChiselDB = true) 103 }), tail) 104 case "--with-rollingdb" :: tail => 105 nextOption(config.alter((site, here, up) => { 106 case DebugOptionsKey => up(DebugOptionsKey).copy(EnableRollingDB = true) 107 }), tail) 108 case "--with-constantin" :: tail => 109 nextOption(config.alter((site, here, up) => { 110 case DebugOptionsKey => up(DebugOptionsKey).copy(EnableConstantin = true) 111 }), tail) 112 case "--fpga-platform" :: tail => 113 nextOption(config.alter((site, here, up) => { 114 case DebugOptionsKey => up(DebugOptionsKey).copy(FPGAPlatform = true) 115 }), tail) 116 case "--reset-gen" :: tail => 117 nextOption(config.alter((site, here, up) => { 118 case DebugOptionsKey => up(DebugOptionsKey).copy(ResetGen = true) 119 }), tail) 120 case "--enable-difftest" :: tail => 121 nextOption(config.alter((site, here, up) => { 122 case DebugOptionsKey => up(DebugOptionsKey).copy(EnableDifftest = true) 123 }), tail) 124 case "--disable-always-basic-diff" :: tail => 125 nextOption(config.alter((site, here, up) => { 126 case DebugOptionsKey => up(DebugOptionsKey).copy(AlwaysBasicDiff = false) 127 }), tail) 128 case "--enable-log" :: tail => 129 nextOption(config.alter((site, here, up) => { 130 case DebugOptionsKey => up(DebugOptionsKey).copy(EnableDebug = true) 131 }), tail) 132 case "--disable-perf" :: tail => 133 nextOption(config.alter((site, here, up) => { 134 case DebugOptionsKey => up(DebugOptionsKey).copy(EnablePerfDebug = false) 135 }), tail) 136 case "--perf-level" :: value :: tail => 137 nextOption(config.alter((site, here, up) => { 138 case DebugOptionsKey => up(DebugOptionsKey).copy(PerfLevel = value) 139 }), tail) 140 case "--disable-alwaysdb" :: tail => 141 nextOption(config.alter((site, here, up) => { 142 case DebugOptionsKey => up(DebugOptionsKey).copy(AlwaysBasicDB = false) 143 }), tail) 144 case "--xstop-prefix" :: value :: tail => 145 nextOption(config.alter((site, here, up) => { 146 case SoCParamsKey => up(SoCParamsKey).copy(XSTopPrefix = Some(value)) 147 }), tail) 148 case "--imsic-bus-type" :: value :: tail => 149 nextOption(config.alter((site, here, up) => { 150 case SoCParamsKey => up(SoCParamsKey).copy(IMSICBusType = device.IMSICBusType.withName(value)) 151 }), tail) 152 case "--firtool-opt" :: option :: tail => 153 firtoolOpts ++= option.split(" ").filter(_.nonEmpty) 154 nextOption(config, tail) 155 case "--l2-cache-size" :: value :: tail => 156 nextOption(config.alter((site, here, up) => { 157 case XSTileKey => 158 val tileParams = up(XSTileKey) 159 val banks = tileParams.map(_.L2NBanks) 160 val ways = tileParams.map(_.L2CacheParamsOpt.map(_.ways)) 161 val l2sets = banks zip ways map { case (banks, ways) => 162 ways.map(value.toInt * 1024 / banks / _ / 64) 163 } 164 val newL2Params = tileParams zip l2sets map { case (tileParam, l2sets) => 165 tileParam.L2CacheParamsOpt.map(_.copy( 166 sets = l2sets.get 167 )) 168 } 169 tileParams zip newL2Params map { case (tileParam, newL2Param) => 170 tileParam.copy(L2CacheParamsOpt = newL2Param) 171 } 172 }), tail) 173 case "--l3-cache-size" :: value :: tail => 174 nextOption(config.alter((site, here, up) => { 175 case SoCParamsKey => 176 val socParam = up(SoCParamsKey) 177 val banks = socParam.L3NBanks 178 val l3Ways = socParam.L3CacheParamsOpt.map(_.ways) 179 val l3Sets = l3Ways.map(value.toInt * 1024 / banks / _ / 64) 180 val openLLCWays = socParam.OpenLLCParamsOpt.map(_.ways) 181 val openLLCSets = openLLCWays.map(value.toInt * 1024 / banks / _ / 64) 182 val newL3Param = socParam.L3CacheParamsOpt.map(_.copy( 183 sets = l3Sets.get 184 )) 185 val openLLCParam = socParam.OpenLLCParamsOpt.map(_.copy( 186 sets = openLLCSets.get 187 )) 188 socParam.copy( 189 L3CacheParamsOpt = newL3Param, 190 OpenLLCParamsOpt = openLLCParam 191 ) 192 }), tail) 193 case "--dfx" :: value :: tail => 194 nextOption(config.alter((site, here, up) => { 195 case XSTileKey => up(XSTileKey).map(_.copy(hasMbist = value.toBoolean)) 196 }), tail) 197 case "--seperate-dm-bus" :: tail => 198 nextOption(config.alter((site, here, up) => { 199 case SoCParamsKey => up(SoCParamsKey).copy(SeperateDMBus = true) 200 }), tail) 201 case "--yaml-config" :: yamlFile :: tail => 202 nextOption(YamlParser.parseYaml(config, yamlFile), tail) 203 case option :: tail => 204 // unknown option, maybe a firrtl option, skip 205 firrtlOpts :+= option 206 nextOption(config, tail) 207 } 208 } 209 val newArgs = DifftestModule.parseArgs(args) 210 val config = nextOption(default, newArgs.toList).alter((site, here, up) => { 211 case LogUtilsOptionsKey => LogUtilsOptions( 212 here(DebugOptionsKey).EnableDebug, 213 here(DebugOptionsKey).EnablePerfDebug, 214 here(DebugOptionsKey).FPGAPlatform 215 ) 216 case PerfCounterOptionsKey => PerfCounterOptions( 217 here(DebugOptionsKey).EnablePerfDebug && !here(DebugOptionsKey).FPGAPlatform, 218 here(DebugOptionsKey).EnableRollingDB && !here(DebugOptionsKey).FPGAPlatform, 219 XSPerfLevel.withName(here(DebugOptionsKey).PerfLevel), 220 0 221 ) 222 }) 223 (config, firrtlOpts, firtoolOpts) 224 } 225} 226