xref: /XiangShan/src/main/scala/top/ArgParser.scala (revision 4daa5bf3c3f27e7fd090866d52405b21e107eb8d)
1/***************************************************************************************
2* Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences
3* Copyright (c) 2020-2021 Peng Cheng Laboratory
4*
5* XiangShan is licensed under Mulan PSL v2.
6* You can use this software according to the terms and conditions of the Mulan PSL v2.
7* You may obtain a copy of Mulan PSL v2 at:
8*          http://license.coscl.org.cn/MulanPSL2
9*
10* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
11* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
12* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
13*
14* See the Mulan PSL v2 for more details.
15***************************************************************************************/
16
17package top
18
19import org.chipsalliance.cde.config.{Config, Parameters}
20import system.SoCParamsKey
21import xiangshan.{DebugOptionsKey, XSTileKey}
22import freechips.rocketchip.tile.MaxHartIdBits
23import difftest.DifftestModule
24
25import scala.annotation.tailrec
26import scala.sys.exit
27import chisel3.util.log2Up
28
29object ArgParser {
30  // TODO: add more explainations
31  val usage =
32    """
33      |XiangShan Options
34      |--xs-help                  print this help message
35      |--config <ConfigClassName>
36      |--num-cores <Int>
37      |--with-dramsim3
38      |--fpga-platform
39      |--enable-difftest
40      |--enable-log
41      |--with-chiseldb
42      |--with-rollingdb
43      |--disable-perf
44      |--disable-alwaysdb
45      |""".stripMargin
46
47  def getConfigByName(confString: String): Parameters = {
48    var prefix = "top." // default package is 'top'
49    if(confString.contains('.')){ // already a full name
50      prefix = ""
51    }
52    val c = Class.forName(prefix + confString).getConstructor(Integer.TYPE)
53    c.newInstance(1.asInstanceOf[Object]).asInstanceOf[Parameters]
54  }
55  def parse(args: Array[String]): (Parameters, Array[String], Array[String]) = {
56    val default = new DefaultConfig(1)
57    var firrtlOpts = Array[String]()
58    var firtoolOpts = Array[String]()
59    @tailrec
60    def nextOption(config: Parameters, list: List[String]): Parameters = {
61      list match {
62        case Nil => config
63        case "--xs-help" :: tail =>
64          println(usage)
65          if(tail == Nil) exit(0)
66          nextOption(config, tail)
67        case "--config" :: confString :: tail =>
68          nextOption(getConfigByName(confString), tail)
69        case "--num-cores" :: value :: tail =>
70          nextOption(config.alter((site, here, up) => {
71            case XSTileKey => (0 until value.toInt) map { i =>
72              up(XSTileKey).head.copy(HartId = i)
73            }
74            case MaxHartIdBits =>
75              require(log2Up(value.toInt) <= 10, "MaxHartIdBits should not be larger than 10.")
76              log2Up(value.toInt)
77          }), tail)
78        case "--with-dramsim3" :: tail =>
79          nextOption(config.alter((site, here, up) => {
80            case DebugOptionsKey => up(DebugOptionsKey).copy(UseDRAMSim = true)
81          }), tail)
82        case "--with-chiseldb" :: tail =>
83          nextOption(config.alter((site, here, up) => {
84            case DebugOptionsKey => up(DebugOptionsKey).copy(EnableChiselDB = true)
85          }), tail)
86        case "--with-rollingdb" :: tail =>
87          nextOption(config.alter((site, here, up) => {
88            case DebugOptionsKey => up(DebugOptionsKey).copy(EnableRollingDB = true)
89          }), tail)
90        case "--with-constantin" :: tail =>
91          nextOption(config.alter((site, here, up) => {
92            case DebugOptionsKey => up(DebugOptionsKey).copy(EnableConstantin = true)
93          }), tail)
94        case "--fpga-platform" :: tail =>
95          nextOption(config.alter((site, here, up) => {
96            case DebugOptionsKey => up(DebugOptionsKey).copy(FPGAPlatform = true)
97          }), tail)
98        case "--enable-difftest" :: tail =>
99          nextOption(config.alter((site, here, up) => {
100            case DebugOptionsKey => up(DebugOptionsKey).copy(EnableDifftest = true)
101          }), tail)
102        case "--disable-always-basic-diff" :: tail =>
103          nextOption(config.alter((site, here, up) => {
104            case DebugOptionsKey => up(DebugOptionsKey).copy(AlwaysBasicDiff = false)
105          }), tail)
106        case "--enable-log" :: tail =>
107          nextOption(config.alter((site, here, up) => {
108            case DebugOptionsKey => up(DebugOptionsKey).copy(EnableDebug = true)
109          }), tail)
110        case "--disable-perf" :: tail =>
111          nextOption(config.alter((site, here, up) => {
112            case DebugOptionsKey => up(DebugOptionsKey).copy(EnablePerfDebug = false)
113          }), tail)
114        case "--disable-alwaysdb" :: tail =>
115          nextOption(config.alter((site, here, up) => {
116            case DebugOptionsKey => up(DebugOptionsKey).copy(AlwaysBasicDB = false)
117          }), tail)
118        case "--xstop-prefix" :: value :: tail if chisel3.BuildInfo.version != "3.6.0" =>
119          nextOption(config.alter((site, here, up) => {
120            case SoCParamsKey => up(SoCParamsKey).copy(XSTopPrefix = Some(value))
121          }), tail)
122        case "--firtool-opt" :: option :: tail =>
123          firtoolOpts ++= option.split(" ").filter(_.nonEmpty)
124          nextOption(config, tail)
125        case option :: tail =>
126          // unknown option, maybe a firrtl option, skip
127          firrtlOpts :+= option
128          nextOption(config, tail)
129      }
130    }
131    val newArgs = DifftestModule.parseArgs(args)
132    var config = nextOption(default, newArgs.toList)
133    (config, firrtlOpts, firtoolOpts)
134  }
135}
136