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.toInt 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 "--enable-ns" :: tail => 153 nextOption(config.alter((site, here, up) => { 154 case coupledL2.tl2chi.NonSecureKey => true 155 }), tail) 156 case "--firtool-opt" :: option :: tail => 157 firtoolOpts ++= option.split(" ").filter(_.nonEmpty) 158 nextOption(config, tail) 159 case "--l2-cache-size" :: value :: tail => 160 nextOption(config.alter((site, here, up) => { 161 case XSTileKey => 162 val tileParams = up(XSTileKey) 163 val banks = tileParams.map(_.L2NBanks) 164 val ways = tileParams.map(_.L2CacheParamsOpt.map(_.ways)) 165 val l2sets = banks zip ways map { case (banks, ways) => 166 ways.map(value.toInt * 1024 / banks / _ / 64) 167 } 168 val newL2Params = tileParams zip l2sets map { case (tileParam, l2sets) => 169 tileParam.L2CacheParamsOpt.map(_.copy( 170 sets = l2sets.get 171 )) 172 } 173 tileParams zip newL2Params map { case (tileParam, newL2Param) => 174 tileParam.copy(L2CacheParamsOpt = newL2Param) 175 } 176 }), tail) 177 case "--l3-cache-size" :: value :: tail => 178 nextOption(config.alter((site, here, up) => { 179 case SoCParamsKey => 180 val socParam = up(SoCParamsKey) 181 val banks = socParam.L3NBanks 182 val l3Ways = socParam.L3CacheParamsOpt.map(_.ways) 183 val l3Sets = l3Ways.map(value.toInt * 1024 / banks / _ / 64) 184 val openLLCWays = socParam.OpenLLCParamsOpt.map(_.ways) 185 val openLLCSets = openLLCWays.map(value.toInt * 1024 / banks / _ / 64) 186 val newL3Param = socParam.L3CacheParamsOpt.map(_.copy( 187 sets = l3Sets.get 188 )) 189 val openLLCParam = socParam.OpenLLCParamsOpt.map(_.copy( 190 sets = openLLCSets.get 191 )) 192 socParam.copy( 193 L3CacheParamsOpt = newL3Param, 194 OpenLLCParamsOpt = openLLCParam 195 ) 196 }), tail) 197 case "--dfx" :: value :: tail => 198 nextOption(config.alter((site, here, up) => { 199 case XSTileKey => up(XSTileKey).map(_.copy(hasMbist = value.toBoolean)) 200 }), tail) 201 case "--sram-with-ctl" :: tail => 202 nextOption(config.alter((site, here, up) => { 203 case XSTileKey => up(XSTileKey).map(_.copy(hasSramCtl = true)) 204 }), tail) 205 case "--seperate-tl-bus" :: tail => 206 nextOption(config.alter((site, here, up) => { 207 case SoCParamsKey => up(SoCParamsKey).copy(SeperateTLBus = true) 208 }), tail) 209 case "--seperate-dm" :: tail => 210 nextOption(config.alter((site, here, up) => { 211 case SoCParamsKey => up(SoCParamsKey).copy(SeperateDM = true) 212 }), tail) 213 case "--wfi-resume" :: value :: tail => 214 nextOption(config.alter((site, here, up) => { 215 case XSTileKey => up(XSTileKey).map(_.copy(wfiResume = value.toBoolean)) 216 }), tail) 217 case "--yaml-config" :: yamlFile :: tail => 218 nextOption(YamlParser.parseYaml(config, yamlFile), tail) 219 case option :: tail => 220 // unknown option, maybe a firrtl option, skip 221 firrtlOpts :+= option 222 nextOption(config, tail) 223 } 224 } 225 val newArgs = DifftestModule.parseArgs(args) 226 val config = nextOption(default, newArgs.toList).alter((site, here, up) => { 227 case LogUtilsOptionsKey => LogUtilsOptions( 228 here(DebugOptionsKey).EnableDebug, 229 here(DebugOptionsKey).EnablePerfDebug, 230 here(DebugOptionsKey).FPGAPlatform 231 ) 232 case PerfCounterOptionsKey => PerfCounterOptions( 233 here(DebugOptionsKey).EnablePerfDebug && !here(DebugOptionsKey).FPGAPlatform, 234 here(DebugOptionsKey).EnableRollingDB && !here(DebugOptionsKey).FPGAPlatform, 235 XSPerfLevel.withName(here(DebugOptionsKey).PerfLevel), 236 0 237 ) 238 }) 239 (config, firrtlOpts, firtoolOpts) 240 } 241} 242