xref: /XiangShan/src/main/scala/top/ArgParser.scala (revision 708ceed4afe43fb0ea3a52407e46b2794c573634)
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 chipsalliance.rocketchip.config.{Config, Parameters}
20import system.SoCParamsKey
21import xiangshan.DebugOptionsKey
22
23import scala.annotation.tailrec
24import scala.sys.exit
25
26object ArgParser {
27  // TODO: add more explainations
28  val usage =
29    """
30      |XiangShan Options
31      |--xs-help                  print this help message
32      |--config <ConfigClassName>
33      |--num-cores <Int>
34      |--dual-core                same as '--num-cores 2'
35      |--with-dramsim3
36      |--disable-log
37      |--disable-perf
38      |""".stripMargin
39
40  def getConfigByName(confString: String): Parameters = {
41    var prefix = "top." // default package is 'top'
42    if(confString.contains('.')){ // already a full name
43      prefix = ""
44    }
45    val c = Class.forName(prefix + confString).getConstructor(Integer.TYPE)
46    c.newInstance(1.asInstanceOf[Object]).asInstanceOf[Parameters]
47  }
48  def parse(args: Array[String], fpga: Boolean = true): (Parameters, Array[String]) = {
49    val default = new DefaultConfig(1)
50    var firrtlOpts = Array[String]()
51    @tailrec
52    def nextOption(config: Parameters, list: List[String]): Parameters = {
53      list match {
54        case Nil => config
55        case "--xs-help" :: tail =>
56          println(usage)
57          if(tail == Nil) exit(0)
58          nextOption(config, tail)
59        case "--config" :: confString :: tail =>
60          nextOption(getConfigByName(confString), tail)
61        case "--num-cores" :: value :: tail =>
62          nextOption(config.alter((site, here, up) => {
63            case SoCParamsKey => up(SoCParamsKey).copy(
64              cores = List.tabulate(value.toInt){ i => up(SoCParamsKey).cores.head.copy(HartId = i) }
65            )
66          }), tail)
67        case "--dual-core" :: tail =>
68          nextOption(config, "--num-cores" :: "2" :: tail)
69        case "--with-dramsim3" :: tail =>
70          nextOption(config.alter((site, here, up) => {
71            case DebugOptionsKey => up(DebugOptionsKey).copy(UseDRAMSim = true)
72          }), tail)
73        case "--disable-log" :: tail =>
74          nextOption(config.alter((site, here, up) => {
75            case DebugOptionsKey => up(DebugOptionsKey).copy(EnableDebug = false)
76          }), tail)
77        case "--disable-perf" :: tail =>
78          nextOption(config.alter((site, here, up) => {
79            case DebugOptionsKey => up(DebugOptionsKey).copy(EnablePerfDebug = false)
80          }), tail)
81        case option :: tail =>
82          // unknown option, maybe a firrtl option, skip
83          firrtlOpts :+= option
84          nextOption(config, tail)
85      }
86    }
87    var config = nextOption(default, args.toList)
88    if(!fpga){
89      config = config.alter((site, here, up) => {
90        case DebugOptionsKey => up(DebugOptionsKey).copy(FPGAPlatform = false)
91      })
92    }
93    (config, firrtlOpts)
94  }
95}
96