xref: /XiangShan/src/main/scala/top/ArgParser.scala (revision 720dd6218ef4045360a23b552db1137cbb6e6e59)
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      |--hartidbits <Int>
38      |--with-dramsim3
39      |--fpga-platform
40      |--reset-gen
41      |--enable-difftest
42      |--enable-log
43      |--with-chiseldb
44      |--with-rollingdb
45      |--disable-perf
46      |--disable-alwaysdb
47      |""".stripMargin
48
49  def getConfigByName(confString: String): Parameters = {
50    var prefix = "top." // default package is 'top'
51    if(confString.contains('.')){ // already a full name
52      prefix = ""
53    }
54    val c = Class.forName(prefix + confString).getConstructor(Integer.TYPE)
55    c.newInstance(1.asInstanceOf[Object]).asInstanceOf[Parameters]
56  }
57  def parse(args: Array[String]): (Parameters, Array[String], Array[String]) = {
58    val default = new DefaultConfig(1)
59    var firrtlOpts = Array[String]()
60    var firtoolOpts = Array[String]()
61    @tailrec
62    def nextOption(config: Parameters, list: List[String]): Parameters = {
63      list match {
64        case Nil => config
65        case "--xs-help" :: tail =>
66          println(usage)
67          if(tail == Nil) exit(0)
68          nextOption(config, tail)
69        case "--config" :: confString :: tail =>
70          nextOption(getConfigByName(confString), tail)
71        case "--num-cores" :: value :: tail =>
72          nextOption(config.alter((site, here, up) => {
73            case XSTileKey => (0 until value.toInt) map { i =>
74              up(XSTileKey).head.copy(HartId = i)
75            }
76            case MaxHartIdBits =>
77              log2Up(value.toInt) max up(MaxHartIdBits)
78          }), tail)
79        case "--hartidbits" :: hartidbits :: tail =>
80          nextOption(config.alter((site, here, up) => {
81            case MaxHartIdBits => hartidbits
82          }), tail)
83        case "--with-dramsim3" :: tail =>
84          nextOption(config.alter((site, here, up) => {
85            case DebugOptionsKey => up(DebugOptionsKey).copy(UseDRAMSim = true)
86          }), tail)
87        case "--with-chiseldb" :: tail =>
88          nextOption(config.alter((site, here, up) => {
89            case DebugOptionsKey => up(DebugOptionsKey).copy(EnableChiselDB = true)
90          }), tail)
91        case "--with-rollingdb" :: tail =>
92          nextOption(config.alter((site, here, up) => {
93            case DebugOptionsKey => up(DebugOptionsKey).copy(EnableRollingDB = true)
94          }), tail)
95        case "--with-constantin" :: tail =>
96          nextOption(config.alter((site, here, up) => {
97            case DebugOptionsKey => up(DebugOptionsKey).copy(EnableConstantin = true)
98          }), tail)
99        case "--fpga-platform" :: tail =>
100          nextOption(config.alter((site, here, up) => {
101            case DebugOptionsKey => up(DebugOptionsKey).copy(FPGAPlatform = true)
102          }), tail)
103        case "--reset-gen" :: tail =>
104          nextOption(config.alter((site, here, up) => {
105            case DebugOptionsKey => up(DebugOptionsKey).copy(ResetGen = true)
106          }), tail)
107        case "--enable-difftest" :: tail =>
108          nextOption(config.alter((site, here, up) => {
109            case DebugOptionsKey => up(DebugOptionsKey).copy(EnableDifftest = true)
110          }), tail)
111        case "--disable-always-basic-diff" :: tail =>
112          nextOption(config.alter((site, here, up) => {
113            case DebugOptionsKey => up(DebugOptionsKey).copy(AlwaysBasicDiff = false)
114          }), tail)
115        case "--enable-log" :: tail =>
116          nextOption(config.alter((site, here, up) => {
117            case DebugOptionsKey => up(DebugOptionsKey).copy(EnableDebug = true)
118          }), tail)
119        case "--disable-perf" :: tail =>
120          nextOption(config.alter((site, here, up) => {
121            case DebugOptionsKey => up(DebugOptionsKey).copy(EnablePerfDebug = false)
122          }), tail)
123        case "--disable-alwaysdb" :: tail =>
124          nextOption(config.alter((site, here, up) => {
125            case DebugOptionsKey => up(DebugOptionsKey).copy(AlwaysBasicDB = false)
126          }), tail)
127        case "--xstop-prefix" :: value :: tail if chisel3.BuildInfo.version != "3.6.0" =>
128          nextOption(config.alter((site, here, up) => {
129            case SoCParamsKey => up(SoCParamsKey).copy(XSTopPrefix = Some(value))
130          }), tail)
131        case "--imsic-use-tl" :: tail =>
132          nextOption(config.alter((site, here, up) => {
133            case SoCParamsKey => up(SoCParamsKey).copy(IMSICUseTL = true)
134          }), tail)
135        case "--firtool-opt" :: option :: tail =>
136          firtoolOpts ++= option.split(" ").filter(_.nonEmpty)
137          nextOption(config, tail)
138        case option :: tail =>
139          // unknown option, maybe a firrtl option, skip
140          firrtlOpts :+= option
141          nextOption(config, tail)
142      }
143    }
144    val newArgs = DifftestModule.parseArgs(args)
145    var config = nextOption(default, newArgs.toList)
146    (config, firrtlOpts, firtoolOpts)
147  }
148}
149