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