xref: /XiangShan/src/main/scala/top/ArgParser.scala (revision c6d439803a044ea209139672b25e35fe8d7f4aa0)
1/***************************************************************************************
2* Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences
3*
4* XiangShan is licensed under Mulan PSL v2.
5* You can use this software according to the terms and conditions of the Mulan PSL v2.
6* You may obtain a copy of Mulan PSL v2 at:
7*          http://license.coscl.org.cn/MulanPSL2
8*
9* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
10* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
11* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
12*
13* See the Mulan PSL v2 for more details.
14***************************************************************************************/
15
16package top
17
18import chipsalliance.rocketchip.config.{Config, Parameters}
19import system.SoCParamsKey
20import xiangshan.DebugOptionsKey
21
22import scala.annotation.tailrec
23import scala.sys.exit
24
25object ArgParser {
26  // TODO: add more explainations
27  val usage =
28    """
29      |XiangShan Options
30      |--xs-help                  print this help message
31      |--config <ConfigClassName>
32      |--num-cores <Int>
33      |--dual-core                same as '--num-cores 2'
34      |--with-dramsim3
35      |--disable-log
36      |--disable-perf
37      |""".stripMargin
38
39  def getConfigByName(confString: String): Parameters = {
40    var prefix = "top." // default package is 'top'
41    if(confString.contains('.')){ // already a full name
42      prefix = ""
43    }
44    val c = Class.forName(prefix + confString).getConstructor(Integer.TYPE)
45    c.newInstance(1.asInstanceOf[Object]).asInstanceOf[Parameters]
46  }
47  def parse(args: Array[String], fpga: Boolean = true): (Parameters, Array[String]) = {
48    val default = new DefaultConfig(1)
49    var firrtlOpts = Array[String]()
50    @tailrec
51    def nextOption(config: Parameters, list: List[String]): Parameters = {
52      list match {
53        case Nil => config
54        case "--xs-help" :: tail =>
55          println(usage)
56          if(tail == Nil) exit(0)
57          nextOption(config, tail)
58        case "--config" :: confString :: tail =>
59          nextOption(getConfigByName(confString), tail)
60        case "--num-cores" :: value :: tail =>
61          nextOption(config.alter((site, here, up) => {
62            case SoCParamsKey => up(SoCParamsKey).copy(
63              cores = List.tabulate(value.toInt){ i => up(SoCParamsKey).cores.head.copy(HartId = i) }
64            )
65          }), tail)
66        case "--dual-core" :: tail =>
67          nextOption(config, "--num-cores" :: "2" :: tail)
68        case "--with-dramsim3" :: tail =>
69          nextOption(config.alter((site, here, up) => {
70            case DebugOptionsKey => up(DebugOptionsKey).copy(UseDRAMSim = true)
71          }), tail)
72        case "--disable-log" :: tail =>
73          nextOption(config.alter((site, here, up) => {
74            case DebugOptionsKey => up(DebugOptionsKey).copy(EnableDebug = false)
75          }), tail)
76        case "--disable-perf" :: tail =>
77          nextOption(config.alter((site, here, up) => {
78            case DebugOptionsKey => up(DebugOptionsKey).copy(EnablePerfDebug = false)
79          }), tail)
80        case option :: tail =>
81          // unknown option, maybe a firrtl option, skip
82          firrtlOpts :+= option
83          nextOption(config, tail)
84      }
85    }
86    var config = nextOption(default, args.toList)
87    if(!fpga){
88      config = config.alter((site, here, up) => {
89        case DebugOptionsKey => up(DebugOptionsKey).copy(FPGAPlatform = false)
90      })
91    }
92    (config, firrtlOpts)
93  }
94}
95