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