xref: /XiangShan/src/main/scala/top/ArgParser.scala (revision 5bd65c56355db1d4f5b92a3815df78273c01b892)
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 "--yaml-config" :: yamlFile :: tail =>
188          nextOption(YamlParser.parseYaml(config, yamlFile), tail)
189        case option :: tail =>
190          // unknown option, maybe a firrtl option, skip
191          firrtlOpts :+= option
192          nextOption(config, tail)
193      }
194    }
195    val newArgs = DifftestModule.parseArgs(args)
196    val config = nextOption(default, newArgs.toList).alter((site, here, up) => {
197      case LogUtilsOptionsKey => LogUtilsOptions(
198        here(DebugOptionsKey).EnableDebug,
199        here(DebugOptionsKey).EnablePerfDebug,
200        here(DebugOptionsKey).FPGAPlatform
201      )
202      case PerfCounterOptionsKey => PerfCounterOptions(
203        here(DebugOptionsKey).EnablePerfDebug && !here(DebugOptionsKey).FPGAPlatform,
204        here(DebugOptionsKey).EnableRollingDB && !here(DebugOptionsKey).FPGAPlatform,
205        0
206      )
207    })
208    (config, firrtlOpts, firtoolOpts)
209  }
210}
211