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