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