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