1c6d43980SLemover#*************************************************************************************** 2c6d43980SLemover# Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences 3f320e0f0SYinan Xu# Copyright (c) 2020-2021 Peng Cheng Laboratory 4c6d43980SLemover# 5c6d43980SLemover# XiangShan is licensed under Mulan PSL v2. 6c6d43980SLemover# You can use this software according to the terms and conditions of the Mulan PSL v2. 7c6d43980SLemover# You may obtain a copy of Mulan PSL v2 at: 8c6d43980SLemover# http://license.coscl.org.cn/MulanPSL2 9c6d43980SLemover# 10c6d43980SLemover# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, 11c6d43980SLemover# EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, 12c6d43980SLemover# MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. 13c6d43980SLemover# 14c6d43980SLemover# See the Mulan PSL v2 for more details. 15c6d43980SLemover#*************************************************************************************** 16c6d43980SLemover 17c11a4d2cSYinan Xu# Simple version of xiangshan python wrapper 18c11a4d2cSYinan Xu 19c11a4d2cSYinan Xuimport argparse 2059bcbb59SYinan Xuimport os 2159bcbb59SYinan Xuimport random 22c11a4d2cSYinan Xuimport subprocess 2359bcbb59SYinan Xuimport sys 245ef7374fSLi Qianruoimport time 25c11a4d2cSYinan Xu 2694e266cbSYinan Xuimport psutil 2794e266cbSYinan Xu 28c11a4d2cSYinan Xu 29c11a4d2cSYinan Xuclass XSArgs(object): 30c11a4d2cSYinan Xu script_path = os.path.realpath(__file__) 31c11a4d2cSYinan Xu # default path to the repositories 32c11a4d2cSYinan Xu noop_home = os.path.join(os.path.dirname(script_path), "..") 33c11a4d2cSYinan Xu nemu_home = os.path.join(noop_home, "../NEMU") 34c11a4d2cSYinan Xu am_home = os.path.join(noop_home, "../nexus-am") 35c11a4d2cSYinan Xu dramsim3_home = os.path.join(noop_home, "../DRAMsim3") 36c11a4d2cSYinan Xu rvtest_home = os.path.join(noop_home, "../riscv-tests") 3724e2eab6SJinYue default_wave_home = os.path.join(noop_home, "build") 3824e2eab6SJinYue wave_home = default_wave_home 39c11a4d2cSYinan Xu 40c11a4d2cSYinan Xu def __init__(self, args): 41c11a4d2cSYinan Xu # all path environment variables that should be set 42c11a4d2cSYinan Xu all_path = [ 43c11a4d2cSYinan Xu # (python argument, environment variable, default, target function) 44c11a4d2cSYinan Xu (None, "NOOP_HOME", self.noop_home, self.set_noop_home), 45c11a4d2cSYinan Xu (args.nemu, "NEMU_HOME", self.nemu_home, self.set_nemu_home), 46c11a4d2cSYinan Xu (args.am, "AM_HOME", self.am_home, self.set_am_home), 47c11a4d2cSYinan Xu (args.dramsim3, "DRAMSIM3_HOME", self.dramsim3_home, self.set_dramsim3_home), 48c11a4d2cSYinan Xu (args.rvtest, "RVTEST_HOME", self.rvtest_home, self.set_rvtest_home), 49c11a4d2cSYinan Xu ] 50c11a4d2cSYinan Xu for (arg_in, env, default, set_func) in all_path: 51c11a4d2cSYinan Xu set_func(self.__extract_path(arg_in, env, default)) 52c11a4d2cSYinan Xu # Chisel arguments 531545277aSYinan Xu self.enable_log = args.enable_log 545ef7374fSLi Qianruo self.num_cores = args.num_cores 55c11a4d2cSYinan Xu # Makefile arguments 56c11a4d2cSYinan Xu self.threads = args.threads 57c11a4d2cSYinan Xu self.with_dramsim3 = 1 if args.with_dramsim3 else None 581545277aSYinan Xu self.is_release = 1 if args.release else None 59eb852d4cSJinYue self.trace = 1 if args.trace or not args.disable_fork else None 606c0058d3SYinan Xu self.config = args.config 61c11a4d2cSYinan Xu # emu arguments 62c11a4d2cSYinan Xu self.max_instr = args.max_instr 6359bcbb59SYinan Xu self.seed = random.randint(0, 9999) 64c11a4d2cSYinan Xu self.numa = args.numa 65f9930da0SYinan Xu self.diff = args.diff 66078fde2bSJinYue self.fork = not args.disable_fork 67*9c297294SWilliam Wang self.disable_diff = args.no_diff 6824e2eab6SJinYue # wave dump path 6924e2eab6SJinYue if args.wave_dump is not None: 7024e2eab6SJinYue self.set_wave_home(args.wave_dump) 7124e2eab6SJinYue else: 7224e2eab6SJinYue self.set_wave_home(self.default_wave_home) 73c11a4d2cSYinan Xu 74c11a4d2cSYinan Xu def get_env_variables(self): 75c11a4d2cSYinan Xu all_env = { 76c11a4d2cSYinan Xu "NOOP_HOME" : self.noop_home, 77c11a4d2cSYinan Xu "NEMU_HOME" : self.nemu_home, 7824e2eab6SJinYue "WAVE_HOME" : self.wave_home, 79c11a4d2cSYinan Xu "AM_HOME" : self.am_home, 80c11a4d2cSYinan Xu "DRAMSIM3_HOME": self.dramsim3_home 81c11a4d2cSYinan Xu } 82c11a4d2cSYinan Xu return all_env 83c11a4d2cSYinan Xu 84c11a4d2cSYinan Xu def get_chisel_args(self, prefix=None): 85c11a4d2cSYinan Xu chisel_args = [ 861545277aSYinan Xu (self.enable_log, "enable-log") 87c11a4d2cSYinan Xu ] 88c11a4d2cSYinan Xu args = map(lambda x: x[1], filter(lambda arg: arg[0], chisel_args)) 89c11a4d2cSYinan Xu if prefix is not None: 90c11a4d2cSYinan Xu args = map(lambda x: prefix + x, args) 91c11a4d2cSYinan Xu return args 92c11a4d2cSYinan Xu 93c11a4d2cSYinan Xu def get_makefile_args(self): 94c11a4d2cSYinan Xu makefile_args = [ 95c11a4d2cSYinan Xu (self.threads, "EMU_THREADS"), 96c11a4d2cSYinan Xu (self.with_dramsim3, "WITH_DRAMSIM3"), 971545277aSYinan Xu (self.is_release, "RELEASE"), 986c0058d3SYinan Xu (self.trace, "EMU_TRACE"), 995ef7374fSLi Qianruo (self.config, "CONFIG"), 1005ef7374fSLi Qianruo (self.num_cores, "NUM_CORES") 101c11a4d2cSYinan Xu ] 102c11a4d2cSYinan Xu args = filter(lambda arg: arg[0] is not None, makefile_args) 103c11a4d2cSYinan Xu return args 104c11a4d2cSYinan Xu 105c11a4d2cSYinan Xu def get_emu_args(self): 106c11a4d2cSYinan Xu emu_args = [ 10759bcbb59SYinan Xu (self.max_instr, "max-instr"), 108f9930da0SYinan Xu (self.diff, "diff"), 10959bcbb59SYinan Xu (self.seed, "seed") 110c11a4d2cSYinan Xu ] 111c11a4d2cSYinan Xu args = filter(lambda arg: arg[0] is not None, emu_args) 112c11a4d2cSYinan Xu return args 113c11a4d2cSYinan Xu 114c11a4d2cSYinan Xu def show(self): 115c11a4d2cSYinan Xu print("Extra environment variables:") 116c11a4d2cSYinan Xu env = self.get_env_variables() 117c11a4d2cSYinan Xu for env_name in env: 118c11a4d2cSYinan Xu print(f"{env_name}: {env[env_name]}") 119c11a4d2cSYinan Xu print() 120c11a4d2cSYinan Xu print("Chisel arguments:") 121c11a4d2cSYinan Xu print(" ".join(self.get_chisel_args())) 122c11a4d2cSYinan Xu print() 123c11a4d2cSYinan Xu print("Makefile arguments:") 124c11a4d2cSYinan Xu for val, name in self.get_makefile_args(): 125c11a4d2cSYinan Xu print(f"{name}={val}") 126c11a4d2cSYinan Xu print() 127c11a4d2cSYinan Xu print("emu arguments:") 128c11a4d2cSYinan Xu for val, name in self.get_emu_args(): 129c11a4d2cSYinan Xu print(f"--{name} {val}") 130c11a4d2cSYinan Xu print() 131c11a4d2cSYinan Xu 132c11a4d2cSYinan Xu def __extract_path(self, path, env=None, default=None): 133c11a4d2cSYinan Xu if path is None and env is not None: 134c11a4d2cSYinan Xu path = os.getenv(env) 135c11a4d2cSYinan Xu if path is None and default is not None: 136c11a4d2cSYinan Xu path = default 137c11a4d2cSYinan Xu path = os.path.realpath(path) 138c11a4d2cSYinan Xu return path 139c11a4d2cSYinan Xu 140c11a4d2cSYinan Xu def set_noop_home(self, path): 141c11a4d2cSYinan Xu self.noop_home = path 142c11a4d2cSYinan Xu 143c11a4d2cSYinan Xu def set_nemu_home(self, path): 144c11a4d2cSYinan Xu self.nemu_home = path 145c11a4d2cSYinan Xu 146c11a4d2cSYinan Xu def set_am_home(self, path): 147c11a4d2cSYinan Xu self.am_home = path 148c11a4d2cSYinan Xu 149c11a4d2cSYinan Xu def set_dramsim3_home(self, path): 150c11a4d2cSYinan Xu self.dramsim3_home = path 151c11a4d2cSYinan Xu 152c11a4d2cSYinan Xu def set_rvtest_home(self, path): 153c11a4d2cSYinan Xu self.rvtest_home = path 154c11a4d2cSYinan Xu 15524e2eab6SJinYue def set_wave_home(self, path): 15624e2eab6SJinYue print(f"set wave home to {path}") 15724e2eab6SJinYue self.wave_home = path 15824e2eab6SJinYue 159c11a4d2cSYinan Xu# XiangShan environment 160c11a4d2cSYinan Xuclass XiangShan(object): 161c11a4d2cSYinan Xu def __init__(self, args): 162c11a4d2cSYinan Xu self.args = XSArgs(args) 163c11a4d2cSYinan Xu 164c11a4d2cSYinan Xu def show(self): 165c11a4d2cSYinan Xu self.args.show() 166c11a4d2cSYinan Xu 167c11a4d2cSYinan Xu def generate_verilog(self): 168c11a4d2cSYinan Xu print("Generating XiangShan verilog with the following configurations:") 169c11a4d2cSYinan Xu self.show() 170c11a4d2cSYinan Xu sim_args = " ".join(self.args.get_chisel_args(prefix="--")) 171c11a4d2cSYinan Xu make_args = " ".join(map(lambda arg: f"{arg[1]}={arg[0]}", self.args.get_makefile_args())) 172c11a4d2cSYinan Xu return_code = self.__exec_cmd(f'make -C $NOOP_HOME verilog SIM_ARGS="{sim_args}" {make_args}') 173c11a4d2cSYinan Xu return return_code 174c11a4d2cSYinan Xu 175c11a4d2cSYinan Xu def build_emu(self): 176c11a4d2cSYinan Xu print("Building XiangShan emu with the following configurations:") 177c11a4d2cSYinan Xu self.show() 178c11a4d2cSYinan Xu sim_args = " ".join(self.args.get_chisel_args(prefix="--")) 179c11a4d2cSYinan Xu make_args = " ".join(map(lambda arg: f"{arg[1]}={arg[0]}", self.args.get_makefile_args())) 180a3e87608SWilliam Wang return_code = self.__exec_cmd(f'make -C $NOOP_HOME emu -j200 SIM_ARGS="{sim_args}" {make_args}') 181c11a4d2cSYinan Xu return return_code 182c11a4d2cSYinan Xu 183c11a4d2cSYinan Xu def run_emu(self, workload): 184c11a4d2cSYinan Xu print("Running XiangShan emu with the following configurations:") 185c11a4d2cSYinan Xu self.show() 186c11a4d2cSYinan Xu emu_args = " ".join(map(lambda arg: f"--{arg[1]} {arg[0]}", self.args.get_emu_args())) 187c11a4d2cSYinan Xu print("workload:", workload) 18894e266cbSYinan Xu numa_info = get_free_cores(self.args.threads) 18994e266cbSYinan Xu numa_args = f"numactl -m {numa_info[0]} -C {numa_info[1]}-{numa_info[2]}" if self.args.numa else "" 190078fde2bSJinYue fork_args = "--enable-fork" if self.args.fork else "" 191*9c297294SWilliam Wang diff_args = "--no-diff" if self.args.disable_diff else "" 192*9c297294SWilliam Wang return_code = self.__exec_cmd(f'{numa_args} $NOOP_HOME/build/emu -i {workload} {emu_args} {fork_args} {diff_args}') 193c11a4d2cSYinan Xu return return_code 194c11a4d2cSYinan Xu 195c11a4d2cSYinan Xu def run(self, args): 196c11a4d2cSYinan Xu if args.ci is not None: 197c11a4d2cSYinan Xu return self.run_ci(args.ci) 198c11a4d2cSYinan Xu actions = [ 199c11a4d2cSYinan Xu (args.generate, lambda _ : self.generate_verilog()), 200c11a4d2cSYinan Xu (args.build, lambda _ : self.build_emu()), 201c11a4d2cSYinan Xu (args.workload, lambda args: self.run_emu(args.workload)) 202c11a4d2cSYinan Xu ] 203c11a4d2cSYinan Xu valid_actions = map(lambda act: act[1], filter(lambda act: act[0], actions)) 204c11a4d2cSYinan Xu for i, action in enumerate(valid_actions): 205c11a4d2cSYinan Xu print(f"Action {i}:") 206c11a4d2cSYinan Xu ret = action(args) 207c11a4d2cSYinan Xu if ret: 208c11a4d2cSYinan Xu return ret 209c11a4d2cSYinan Xu return 0 210c11a4d2cSYinan Xu 211c11a4d2cSYinan Xu def __exec_cmd(self, cmd): 212c11a4d2cSYinan Xu env = dict(os.environ) 213c11a4d2cSYinan Xu env.update(self.args.get_env_variables()) 214c11a4d2cSYinan Xu print("subprocess call cmd:", cmd) 2155ef7374fSLi Qianruo start = time.time() 216c11a4d2cSYinan Xu return_code = subprocess.call(cmd, shell=True, env=env) 2175ef7374fSLi Qianruo end = time.time() 2185ef7374fSLi Qianruo print(f"Elapsed time: {end - start} seconds") 219c11a4d2cSYinan Xu return return_code 220c11a4d2cSYinan Xu 221c11a4d2cSYinan Xu def __get_ci_cputest(self, name=None): 222c11a4d2cSYinan Xu base_dir = os.path.join(self.args.am_home, "tests/cputest/build") 223c11a4d2cSYinan Xu cputest = os.listdir(base_dir) 224c11a4d2cSYinan Xu cputest = filter(lambda x: x.endswith(".bin"), cputest) 225c11a4d2cSYinan Xu cputest = map(lambda x: os.path.join(base_dir, x), cputest) 226c11a4d2cSYinan Xu return cputest 227c11a4d2cSYinan Xu 228c11a4d2cSYinan Xu def __get_ci_rvtest(self, name=None): 229c11a4d2cSYinan Xu base_dir = os.path.join(self.args.rvtest_home, "isa/build") 230c11a4d2cSYinan Xu riscv_tests = os.listdir(base_dir) 231c11a4d2cSYinan Xu riscv_tests = filter(lambda x: x.endswith(".bin"), riscv_tests) 232c11a4d2cSYinan Xu all_rv_tests = ["rv64ui", "rv64um", "rv64ua", "rv64uf", "rv64ud"] 233c11a4d2cSYinan Xu riscv_tests = filter(lambda x: x[:6] in all_rv_tests, riscv_tests) 234c11a4d2cSYinan Xu riscv_tests = map(lambda x: os.path.join(base_dir, x), riscv_tests) 235c11a4d2cSYinan Xu return riscv_tests 236c11a4d2cSYinan Xu 237675acc68SYinan Xu def __get_ci_misc(self, name=None): 238675acc68SYinan Xu base_dir = "/home/ci-runner/xsenv/workloads" 239675acc68SYinan Xu workloads = [ 240675acc68SYinan Xu "bitmanip/bitMisc.bin", 2413feeca58Szfw "crypto/crypto-riscv64-noop.bin", 242675acc68SYinan Xu "coremark_rv64gc_o2/coremark-riscv64-xs.bin", 243675acc68SYinan Xu "coremark_rv64gc_o3/coremark-riscv64-xs.bin", 24464a887e0SYinan Xu "coremark_rv64gcb_o3/coremark-riscv64-xs.bin", 24535620aa8Swakafa "ext_intr/amtest-riscv64-xs.bin", 2463f4ec46fSCODE-JTZ "cache-alias/aliastest-riscv64-xs.bin", 247af2f7849Shappy-lx "Svinval/rv64mi-p-svinval.bin", 248b6982e83SLemover "pmp/pmp.riscv.bin", 24945f497a4Shappy-lx "asid/asid.bin", 2507d9edc86SLemover "isa_misc/xret_clear_mprv.bin", 251705cbec3SLemover "isa_misc/satp_ppn.bin", 252*9c297294SWilliam Wang "cache-management/softprefetchtest-riscv64-xs.bin" 253675acc68SYinan Xu ] 254675acc68SYinan Xu misc_tests = map(lambda x: os.path.join(base_dir, x), workloads) 255675acc68SYinan Xu return misc_tests 256675acc68SYinan Xu 257*9c297294SWilliam Wang def __get_ci_nodiff(self, name=None): 258*9c297294SWilliam Wang base_dir = "/home/ci-runner/xsenv/workloads" 259*9c297294SWilliam Wang workloads = [ 260*9c297294SWilliam Wang "cache-management/cacheoptest-riscv64-xs.bin" 261*9c297294SWilliam Wang ] 262*9c297294SWilliam Wang tests = map(lambda x: os.path.join(base_dir, x), workloads) 263*9c297294SWilliam Wang return tests 264*9c297294SWilliam Wang 265c11a4d2cSYinan Xu def __am_apps_path(self, bench): 266c11a4d2cSYinan Xu filename = f"{bench}-riscv64-noop.bin" 267c11a4d2cSYinan Xu return [os.path.join(self.args.am_home, "apps", bench, "build", filename)] 268c11a4d2cSYinan Xu 269c11a4d2cSYinan Xu def __get_ci_workloads(self, name): 270c11a4d2cSYinan Xu workloads = { 271c11a4d2cSYinan Xu "linux-hello": "bbl.bin", 2725092a298Szfw "povray": "_700480000000_.gz", 2735092a298Szfw "mcf": "_17520000000_.gz", 2745092a298Szfw "xalancbmk": "_266100000000_.gz", 2755092a298Szfw "gcc": "_39720000000_.gz", 2765092a298Szfw "namd": "_434640000000_.gz", 2775092a298Szfw "milc": "_103620000000_.gz", 2785092a298Szfw "lbm": "_140840000000_.gz", 2797b441e5eSYinan Xu "gromacs": "_275480000000_.gz", 2807b441e5eSYinan Xu "wrf": "_1916220000000_.gz", 2817b441e5eSYinan Xu "astar": "_122060000000_.gz" 282c11a4d2cSYinan Xu } 283c11a4d2cSYinan Xu return [os.path.join("/home/ci-runner/xsenv/workloads", name, workloads[name])] 284c11a4d2cSYinan Xu 285c11a4d2cSYinan Xu def run_ci(self, test): 286c11a4d2cSYinan Xu all_tests = { 287c11a4d2cSYinan Xu "cputest": self.__get_ci_cputest, 288c11a4d2cSYinan Xu "riscv-tests": self.__get_ci_rvtest, 289675acc68SYinan Xu "misc-tests": self.__get_ci_misc, 290*9c297294SWilliam Wang "nodiff-tests": self.__get_ci_nodiff, 291c11a4d2cSYinan Xu "microbench": self.__am_apps_path, 292c11a4d2cSYinan Xu "coremark": self.__am_apps_path 293c11a4d2cSYinan Xu } 294c11a4d2cSYinan Xu for target in all_tests.get(test, self.__get_ci_workloads)(test): 295c11a4d2cSYinan Xu print(target) 296c11a4d2cSYinan Xu ret = self.run_emu(target) 297c11a4d2cSYinan Xu if ret: 29824e2eab6SJinYue if self.args.default_wave_home != self.args.wave_home: 29924e2eab6SJinYue print("copy wave file to " + self.args.wave_home) 30024e2eab6SJinYue self.__exec_cmd(f"cp $NOOP_HOME/build/*.vcd $WAVE_HOME") 301bc063562SLemover self.__exec_cmd(f"cp $NOOP_HOME/build/emu $WAVE_HOME") 302bc063562SLemover self.__exec_cmd(f"cp $NOOP_HOME/build/SimTop.v $WAVE_HOME") 303c11a4d2cSYinan Xu return ret 304c11a4d2cSYinan Xu return 0 305c11a4d2cSYinan Xu 30694e266cbSYinan Xudef get_free_cores(n): 30794e266cbSYinan Xu while True: 30894e266cbSYinan Xu # To avoid potential conflicts, we allow CI to use SMT. 30994e266cbSYinan Xu num_logical_core = psutil.cpu_count(logical=True) 31094e266cbSYinan Xu core_usage = psutil.cpu_percent(interval=1, percpu=True) 31194e266cbSYinan Xu num_window = num_logical_core // n 31294e266cbSYinan Xu for i in range(num_window): 31394e266cbSYinan Xu window_usage = core_usage[i * n : i * n + n] 31494e266cbSYinan Xu if sum(window_usage) < 0.3 * n and True not in map(lambda x: x > 0.5, window_usage): 31594e266cbSYinan Xu return (((i * n) % 128)// 64, i * n, i * n + n - 1) 31694e266cbSYinan Xu print(f"No free {n} cores found. CPU usage: {core_usage}\n") 31794e266cbSYinan Xu 318c11a4d2cSYinan Xuif __name__ == "__main__": 319c11a4d2cSYinan Xu parser = argparse.ArgumentParser(description='Python wrapper for XiangShan') 320c11a4d2cSYinan Xu parser.add_argument('workload', nargs='?', type=str, default="", 321c11a4d2cSYinan Xu help='input workload file in binary format') 322c11a4d2cSYinan Xu # actions 323c11a4d2cSYinan Xu parser.add_argument('--build', action='store_true', help='build XS emu') 324c11a4d2cSYinan Xu parser.add_argument('--generate', action='store_true', help='generate XS verilog') 325c11a4d2cSYinan Xu parser.add_argument('--ci', nargs='?', type=str, const="", help='run CI tests') 326c11a4d2cSYinan Xu # environment variables 327c11a4d2cSYinan Xu parser.add_argument('--nemu', nargs='?', type=str, help='path to nemu') 328c11a4d2cSYinan Xu parser.add_argument('--am', nargs='?', type=str, help='path to nexus-am') 329c11a4d2cSYinan Xu parser.add_argument('--dramsim3', nargs='?', type=str, help='path to dramsim3') 330c11a4d2cSYinan Xu parser.add_argument('--rvtest', nargs='?', type=str, help='path to riscv-tests') 33124e2eab6SJinYue parser.add_argument('--wave-dump', nargs='?', type=str , help='path to dump wave') 332c11a4d2cSYinan Xu # chisel arguments 3331545277aSYinan Xu parser.add_argument('--enable-log', action='store_true', help='enable log') 3345ef7374fSLi Qianruo parser.add_argument('--num-cores', type=int, help='number of cores') 335c11a4d2cSYinan Xu # makefile arguments 3361545277aSYinan Xu parser.add_argument('--release', action='store_true', help='enable release') 337c11a4d2cSYinan Xu parser.add_argument('--with-dramsim3', action='store_true', help='enable dramsim3') 338c11a4d2cSYinan Xu parser.add_argument('--threads', nargs='?', type=int, help='number of emu threads') 339c11a4d2cSYinan Xu parser.add_argument('--trace', action='store_true', help='enable waveform') 3406c0058d3SYinan Xu parser.add_argument('--config', nargs='?', type=str, help='config') 341c11a4d2cSYinan Xu # emu arguments 342c11a4d2cSYinan Xu parser.add_argument('--numa', action='store_true', help='use numactl') 343f9930da0SYinan Xu parser.add_argument('--diff', nargs='?', default="./ready-to-run/riscv64-nemu-interpreter-so", type=str, help='nemu so') 344c11a4d2cSYinan Xu parser.add_argument('--max-instr', nargs='?', type=int, help='max instr') 345078fde2bSJinYue parser.add_argument('--disable-fork', action='store_true', help='disable lightSSS') 346*9c297294SWilliam Wang parser.add_argument('--no-diff', action='store_true', help='disable difftest') 34724e2eab6SJinYue # ci action head sha 348c11a4d2cSYinan Xu 349c11a4d2cSYinan Xu args = parser.parse_args() 350c11a4d2cSYinan Xu 351c11a4d2cSYinan Xu xs = XiangShan(args) 352c11a4d2cSYinan Xu ret = xs.run(args) 353c11a4d2cSYinan Xu 354c11a4d2cSYinan Xu sys.exit(ret) 355