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._ 30 31object ArgParser { 32 // TODO: add more explainations 33 val usage = 34 """ 35 |XiangShan Options 36 |--xs-help print this help message 37 |--version print version info 38 |--config <ConfigClassName> 39 |--num-cores <Int> 40 |--hartidbits <Int> 41 |--with-dramsim3 42 |--fpga-platform 43 |--reset-gen 44 |--enable-difftest 45 |--enable-log 46 |--with-chiseldb 47 |--with-rollingdb 48 |--disable-perf 49 |--disable-alwaysdb 50 |""".stripMargin 51 52 def getConfigByName(confString: String): Parameters = { 53 var prefix = "top." // default package is 'top' 54 if(confString.contains('.')){ // already a full name 55 prefix = "" 56 } 57 val c = Class.forName(prefix + confString).getConstructor(Integer.TYPE) 58 c.newInstance(1.asInstanceOf[Object]).asInstanceOf[Parameters] 59 } 60 def parse(args: Array[String]): (Parameters, Array[String], Array[String]) = { 61 val default = new DefaultConfig(1) 62 var firrtlOpts = Array[String]() 63 var firtoolOpts = Array[String]() 64 @tailrec 65 def nextOption(config: Parameters, list: List[String]): Parameters = { 66 list match { 67 case Nil => config 68 case "--xs-help" :: tail => 69 println(usage) 70 if(tail == Nil) exit(0) 71 nextOption(config, tail) 72 case "--version" :: tail => 73 println(os.read(os.resource / "publishVersion")) 74 if(tail == Nil) exit(0) 75 nextOption(config, tail) 76 case "--config" :: confString :: tail => 77 nextOption(getConfigByName(confString), tail) 78 case "--issue" :: issueString :: tail => 79 nextOption(config.alter((site, here, up) => { 80 case coupledL2.tl2chi.CHIIssue => issueString 81 }), tail) 82 case "--num-cores" :: value :: tail => 83 nextOption(config.alter((site, here, up) => { 84 case XSTileKey => (0 until value.toInt) map { i => 85 up(XSTileKey).head.copy(HartId = i) 86 } 87 case MaxHartIdBits => 88 log2Up(value.toInt) max up(MaxHartIdBits) 89 }), tail) 90 case "--hartidbits" :: hartidbits :: tail => 91 nextOption(config.alter((site, here, up) => { 92 case MaxHartIdBits => hartidbits 93 }), tail) 94 case "--with-dramsim3" :: tail => 95 nextOption(config.alter((site, here, up) => { 96 case DebugOptionsKey => up(DebugOptionsKey).copy(UseDRAMSim = true) 97 }), tail) 98 case "--with-chiseldb" :: tail => 99 nextOption(config.alter((site, here, up) => { 100 case DebugOptionsKey => up(DebugOptionsKey).copy(EnableChiselDB = true) 101 }), tail) 102 case "--with-rollingdb" :: tail => 103 nextOption(config.alter((site, here, up) => { 104 case DebugOptionsKey => up(DebugOptionsKey).copy(EnableRollingDB = true) 105 }), tail) 106 case "--with-constantin" :: tail => 107 nextOption(config.alter((site, here, up) => { 108 case DebugOptionsKey => up(DebugOptionsKey).copy(EnableConstantin = true) 109 }), tail) 110 case "--fpga-platform" :: tail => 111 nextOption(config.alter((site, here, up) => { 112 case DebugOptionsKey => up(DebugOptionsKey).copy(FPGAPlatform = true) 113 }), tail) 114 case "--reset-gen" :: tail => 115 nextOption(config.alter((site, here, up) => { 116 case DebugOptionsKey => up(DebugOptionsKey).copy(ResetGen = true) 117 }), tail) 118 case "--enable-difftest" :: tail => 119 nextOption(config.alter((site, here, up) => { 120 case DebugOptionsKey => up(DebugOptionsKey).copy(EnableDifftest = true) 121 }), tail) 122 case "--disable-always-basic-diff" :: tail => 123 nextOption(config.alter((site, here, up) => { 124 case DebugOptionsKey => up(DebugOptionsKey).copy(AlwaysBasicDiff = false) 125 }), tail) 126 case "--enable-log" :: tail => 127 nextOption(config.alter((site, here, up) => { 128 case DebugOptionsKey => up(DebugOptionsKey).copy(EnableDebug = true) 129 }), tail) 130 case "--disable-perf" :: tail => 131 nextOption(config.alter((site, here, up) => { 132 case DebugOptionsKey => up(DebugOptionsKey).copy(EnablePerfDebug = false) 133 }), tail) 134 case "--disable-alwaysdb" :: tail => 135 nextOption(config.alter((site, here, up) => { 136 case DebugOptionsKey => up(DebugOptionsKey).copy(AlwaysBasicDB = false) 137 }), tail) 138 case "--xstop-prefix" :: value :: tail => 139 nextOption(config.alter((site, here, up) => { 140 case SoCParamsKey => up(SoCParamsKey).copy(XSTopPrefix = Some(value)) 141 }), tail) 142 case "--imsic-use-tl" :: tail => 143 nextOption(config.alter((site, here, up) => { 144 case SoCParamsKey => up(SoCParamsKey).copy(IMSICUseTL = true) 145 }), tail) 146 case "--firtool-opt" :: option :: tail => 147 firtoolOpts ++= option.split(" ").filter(_.nonEmpty) 148 nextOption(config, tail) 149 case "--l2-cache-size" :: value :: tail => 150 nextOption(config.alter((site, here, up) => { 151 case XSTileKey => 152 val tileParams = up(XSTileKey) 153 val banks = tileParams.map(_.L2NBanks) 154 val ways = tileParams.map(_.L2CacheParamsOpt.map(_.ways)) 155 val l2sets = banks zip ways map { case (banks, ways) => 156 ways.map(value.toInt * 1024 / banks / _ / 64) 157 } 158 val newL2Params = tileParams zip l2sets map { case (tileParam, l2sets) => 159 tileParam.L2CacheParamsOpt.map(_.copy( 160 sets = l2sets.get 161 )) 162 } 163 tileParams zip newL2Params map { case (tileParam, newL2Param) => 164 tileParam.copy(L2CacheParamsOpt = newL2Param) 165 } 166 }), tail) 167 case "--l3-cache-size" :: value :: tail => 168 nextOption(config.alter((site, here, up) => { 169 case SoCParamsKey => 170 val socParam = up(SoCParamsKey) 171 val banks = socParam.L3NBanks 172 val l3Ways = socParam.L3CacheParamsOpt.map(_.ways) 173 val l3Sets = l3Ways.map(value.toInt * 1024 / banks / _ / 64) 174 val openLLCWays = socParam.OpenLLCParamsOpt.map(_.ways) 175 val openLLCSets = openLLCWays.map(value.toInt * 1024 / banks / _ / 64) 176 val newL3Param = socParam.L3CacheParamsOpt.map(_.copy( 177 sets = l3Sets.get 178 )) 179 val openLLCParam = socParam.OpenLLCParamsOpt.map(_.copy( 180 sets = openLLCSets.get 181 )) 182 socParam.copy( 183 L3CacheParamsOpt = newL3Param, 184 OpenLLCParamsOpt = openLLCParam 185 ) 186 }), tail) 187 case option :: tail => 188 // unknown option, maybe a firrtl option, skip 189 firrtlOpts :+= option 190 nextOption(config, tail) 191 } 192 } 193 val newArgs = DifftestModule.parseArgs(args) 194 val config = nextOption(default, newArgs.toList).alter((site, here, up) => { 195 case LogUtilsOptionsKey => LogUtilsOptions( 196 here(DebugOptionsKey).EnableDebug, 197 here(DebugOptionsKey).EnablePerfDebug, 198 here(DebugOptionsKey).FPGAPlatform 199 ) 200 case PerfCounterOptionsKey => PerfCounterOptions( 201 here(DebugOptionsKey).EnablePerfDebug && !here(DebugOptionsKey).FPGAPlatform, 202 here(DebugOptionsKey).EnableRollingDB && !here(DebugOptionsKey).FPGAPlatform, 203 0 204 ) 205 }) 206 (config, firrtlOpts, firtoolOpts) 207 } 208} 209