core-v-verif系列之cva6 cva6.py (5)

cva6.py

cva6.py 文件是一个用于 CORE-V CVA6 项目的 RISC-V 随机指令生成器的回归测试脚本。它负责设置、编译和运行 RISC-V 指令集模拟器(ISS)和 RTL 模拟器的测试。以下是主要功能及其作用:

  1. SeedGen 类:生成测试迭代的伪随机种子。
  2. get_generator_cmd:根据提供的模拟器和配置文件设置编译和模拟指令生成器的命令。
  3. parse_iss_yaml:解析 ISS 的 YAML 配置文件以获取模拟命令。
  4. get_iss_cmd:生成 ISS 模拟命令。
  5. do_compile:编译指令生成器。
  6. run_csr_test:通过生成定向 CSR 测试代码来运行 CSR 测试。
  7. do_simulate:运行指令生成器。
  8. gen:运行指令生成器的主要函数。
  9. elf2bin:将 ELF 文件转换为二进制格式,以用于 RTL 模拟。
  10. gcc_compile:使用 RISC-V GCC 工具链将汇编程序编译为 ELF 文件。
  11. tandem_postprocess:后处理并行模拟结果。
  12. run_test:运行定向的 ISS 测试。
  13. iss_sim:使用生成的测试程序运行 ISS 模拟。
  14. iss_cmp:比较 ISS 模拟结果。

示例输入参数:

  • simulator: 使用的 RTL 模拟器名称。
  • simulator_yaml: RTL 模拟器的 YAML 配置文件。
  • cov: 启用功能覆盖。
  • exp: 使用实验版本。
  • debug_cmd: 生成调试命令日志而不运行。
  • iss_yaml: ISS 的 YAML 配置文件。
  • isa: 指令集架构变体。
  • test_list: 要编译的汇编程序列表。
  • output_dir: 输出文件目录。
  • cwd: 当前工作目录。
  • compile_cmd: 编译指令生成器的命令。
  • sim_cmd: 运行指令生成器的命令。
  • csr_file: 包含所有 CSR 描述的 YAML 文件。
  • iterations: 每个测试的迭代次数。
  • priv: 测试的权限模式。
  • spike_params: Spike ISS 的参数。
  • log_suffix: 模拟日志文件名后缀。
  • batch_size: 每次运行生成的测试数量。
  • verbose: 启用详细日志记录。
  • check_return_code: 检查命令的返回码。
  • gcc_opts: GCC 编译选项。
  • linker: 链接器的路径。

20. read_seed


def read_seed(arg):
    '''Read --seed or --seed_start'''
    try:
        seed = int(arg)
        if seed < 0:
            raise ValueError('bad seed')
        return seed

    except ValueError:
        raise argparse.ArgumentTypeError('Bad seed ({}): '
                                         'must be a non-negative integer.'
                                         .format(arg))

函数 read_seed

read_seed 的函数,用于读取和验证种子参数。

函数定义

def read_seed(arg):
    '''Read --seed or --seed_start'''
    try:
        seed = int(arg)
        if seed < 0:
            raise ValueError('bad seed')
        return seed

    except ValueError:
        raise argparse.ArgumentTypeError('Bad seed ({}): '
                                         'must be a non-negative integer.'
                                         .format(arg))
  • read_seed 函数用于读取和验证种子参数。
  • 参数:
    • arg: 传递的种子参数(字符串格式)。

函数实现

    try:
        seed = int(arg)
        if seed < 0:
            raise ValueError('bad seed')
        return seed
  • 使用 try 块尝试将传递的参数 arg 转换为整数 seed
  • 如果 seed 小于 0,则引发 ValueError 异常,并显示错误消息 'bad seed'
  • 如果转换成功且 seed 为非负整数,则返回 seed
    except ValueError:
        raise argparse.ArgumentTypeError('Bad seed ({}): '
                                         'must be a non-negative integer.'
                                         .format(arg))
  • 如果在转换过程中引发 ValueError 异常,则捕获该异常,并引发 argparse.ArgumentTypeError 异常,显示详细错误消息 'Bad seed (arg): must be a non-negative integer.'

示例

假设我们有以下输入参数:

  • arg: "123"

调用该函数将执行以下操作:

  1. 尝试将 "123" 转换为整数 123
  2. 由于 123 是非负整数,因此返回 123

假设我们有以下输入参数:

  • arg: "-123"

调用该函数将执行以下操作:

  1. 尝试将 "-123" 转换为整数 -123
  2. 由于 -123 是负整数,因此引发 ValueError 异常。
  3. 捕获 ValueError 异常,并引发 argparse.ArgumentTypeError 异常,显示错误消息 'Bad seed (-123): must be a non-negative integer.'

总结

read_seed 函数用于读取和验证种子参数,确保传递的参数是非负整数。如果参数无效,则函数将引发带有详细错误消息的 argparse.ArgumentTypeError 异常。

21. parse_args


def parse_args(cwd):
  """Create a command line parser.

  Returns: The created parser.
  """
  # Parse input arguments
  parser = argparse.ArgumentParser()

  parser.add_argument("--target", type=str, default="rv32imc",
                      help="Run the generator with pre-defined targets: \
                            rv32imc, rv32i, rv32ima, rv64imc, rv64gc, rv64imac")
  parser.add_argument("-o", "--output", type=str,
                      help="Output directory name", dest="o")
  parser.add_argument("-tl", "--testlist", type=str, default="",
                      help="Regression testlist", dest="testlist")
  parser.add_argument("-tn", "--test", type=str, default="all",
                      help="Test name, 'all' means all tests in the list", dest="test")
  parser.add_argument("-i", "--iterations", type=int, default=0,
                      help="Override the iteration count in the test list", dest="iterations")
  parser.add_argument("-si", "--simulator", type=str, default="vcs",
                      help="Simulator used to run the generator, default VCS", dest="simulator")
  parser.add_argument("--iss", type=str, default="spike",
                      help="RISC-V instruction set simulator: spike,ovpsim,sail")
  parser.add_argument("-v", "--verbose", dest="verbose", action="store_true", default=False,
                      help="Verbose logging")
  parser.add_argument("--co", dest="co", action="store_true", default=False,
                      help="Compile the generator only")
  parser.add_argument("--cov", dest="cov", action="store_true", default=False,
                      help="Enable functional coverage")
  parser.add_argument("--so", dest="so", action="store_true", default=False,
                      help="Simulate the generator only")
  parser.add_argument("--cmp_opts", type=str, default="",
                      help="Compile options for the generator")
  parser.add_argument("--sim_opts", type=str, default="",
                      help="Simulation options for the generator")
  parser.add_argument("--gcc_opts", type=str, default="",
                      help="GCC compile options")
  parser.add_argument("--issrun_opts", type=str, default="+debug_disable=1",
                      help="simulation run options")
  parser.add_argument("--isscomp_opts", type=str, default="",
                      help="simulation comp options")
  parser.add_argument("--isspostrun_opts", type=str, default="0x0000000080000000",
                      help="simulation post run options")
  parser.add_argument("-s", "--steps", type=str, default="all",
                      help="Run steps: gen,gcc_compile,iss_sim,iss_cmp", dest="steps")
  parser.add_argument("--lsf_cmd", type=str, default="",
                      help="LSF command. Run in local sequentially if lsf \
                            command is not specified")
  parser.add_argument("--isa", type=str, default="",
                      help="RISC-V ISA subset")
  parser.add_argument("--priv", type=str, default="msu",
                      help="RISC-V ISA privilege models")
  parser.add_argument("-m", "--mabi", type=str, default="",
                      help="mabi used for compilation", dest="mabi")
  parser.add_argument("--gen_timeout", type=int, default=360,
                      help="Generator timeout limit in seconds")
  parser.add_argument("--end_signature_addr", type=str, default="0",
                      help="Address that privileged CSR test writes to at EOT")
  parser.add_argument("--iss_opts", type=str, default="",
                      help="Any ISS command line arguments")
  parser.add_argument("--iss_timeout", type=int, default=500,
                      help="ISS sim timeout limit in seconds")
  parser.add_argument("--iss_yaml", type=str, default="",
                      help="ISS setting YAML")
  parser.add_argument("--simulator_yaml", type=str, default="",
                      help="RTL simulator setting YAML")
  parser.add_argument("--csr_yaml", type=str, default="",
                      help="CSR description file")
  parser.add_argument("-ct", "--custom_target", type=str, default="",
                      help="Directory name of the custom target")
  parser.add_argument("-cs", "--core_setting_dir", type=str, default="",
                      help="Path for the riscv_core_setting.sv")
  parser.add_argument("-ext", "--user_extension_dir", type=str, default="",
                      help="Path for the user extension directory")
  parser.add_argument("--asm_tests", type=str, default="",
                      help="Directed assembly tests")
  parser.add_argument("--c_tests", type=str, default="",
                      help="Directed c tests")
  parser.add_argument("--elf_tests", type=str, default="",
                      help="Directed elf tests")
  parser.add_argument("--log_suffix", type=str, default="",
                      help="Simulation log name suffix")
  parser.add_argument("--exp", action="store_true", default=False,
                      help="Run generator with experimental features")
  parser.add_argument("-bz", "--batch_size", type=int, default=0,
                      help="Number of tests to generate per run. You can split a big"
                           " job to small batches with this option")
  parser.add_argument("--stop_on_first_error", dest="stop_on_first_error",
                      action="store_true", default=False,
                      help="Stop on detecting first error")
  parser.add_argument("--noclean", action="store_true", default=True,
                      help="Do not clean the output of the previous runs")
  parser.add_argument("--verilog_style_check", action="store_true", default=False,
                      help="Run verilog style check")
  parser.add_argument("-d", "--debug", type=str, default="",
                      help="Generate debug command log file")
  parser.add_argument("--hwconfig_opts", type=str, default="",
                      help="custom configuration options for util/user_config.py")
  parser.add_argument("-l", "--linker", type=str, default="",
                      help="Path for the link.ld")
  parser.add_argument("--axi_active", type=str, default="",
                      help="switch AXI agent mode: yes for Active, no for Passive")
  parser.add_argument("--gen_sv_seed", type=int, default=0,
                      help="Run test N times with random seed")
  parser.add_argument("--sv_seed", type=str, default=str(random.getrandbits(31)),
                      help="Run test with a specific seed")
  parser.add_argument("--isa_extension", type=str, default="",
                      help="Choose additional z, s, x extensions")
  parser.add_argument("--spike_params", type=str, default="",
                      help="Spike command line parameters, run spike --help and spike --print-params to see more")
  rsg = parser.add_argument_group('Random seeds',
                                  'To control random seeds, use at most one '
                                  'of the --start_seed, --seed or --seed_yaml '
                                  'arguments. Since the latter two only give '
                                  'a single seed for each test, they imply '
                                  '--iterations=1.')

  rsg.add_argument("--start_seed", type=read_seed,
                   help=("Randomization seed to use for first iteration of "
                         "each test. Subsequent iterations use seeds "
                         "counting up from there. Cannot be used with "
                         "--seed or --seed_yaml."))
  rsg.add_argument("--seed", type=read_seed,
                   help=("Randomization seed to use for each test. "
                         "Implies --iterations=1. Cannot be used with "
                         "--start_seed or --seed_yaml."))
  rsg.add_argument("--seed_yaml", type=str,
                   help=("Rerun the generator with the seed specification "
                         "from a prior regression. Implies --iterations=1. "
                         "Cannot be used with --start_seed or --seed."))

  args = parser.parse_args()

  if args.seed is not None and args.start_seed is not None:
    logging.error('--start_seed and --seed are mutually exclusive.')
    sys.exit(RET_FAIL)

  if args.seed is not None:
    if args.iterations == 0:
      args.iterations = 1
    elif args.iterations > 1:
      logging.error('--seed is incompatible with setting --iterations '
                    'greater than 1.')
      sys.exit(RET_FAIL)

  return args


函数 parse_args

parse_args 的函数,用于创建命令行参数解析器并解析输入参数。

函数定义

def parse_args(cwd):
  """Create a command line parser.

  Returns: The created parser.
  """
  # Parse input arguments
  parser = argparse.ArgumentParser()
  • parse_args 函数用于创建命令行参数解析器并解析输入参数。
  • 参数:
    • cwd: 当前工作目录的路径。

参数定义

  parser.add_argument("--target", type=str, default="rv32imc",
                      help="Run the generator with pre-defined targets: \
                            rv32imc, rv32i, rv32ima, rv64imc, rv64gc, rv64imac")
  • --target: 运行生成器的预定义目标,默认值为 rv32imc
  parser.add_argument("-o", "--output", type=str,
                      help="Output directory name", dest="o")
  • -o--output: 输出目录的名称。
  parser.add_argument("-tl", "--testlist", type=str, default="",
                      help="Regression testlist", dest="testlist")
  • -tl--testlist: 回归测试列表的路径,默认值为空字符串。
  parser.add_argument("-tn", "--test", type=str, default="all",
                      help="Test name, 'all' means all tests in the list", dest="test")
  • -tn--test: 测试名称,默认值为 all,表示测试列表中的所有测试。
  parser.add_argument("-i", "--iterations", type=int, default=0,
                      help="Override the iteration count in the test list", dest="iterations")
  • -i--iterations: 覆盖测试列表中的迭代次数,默认值为 0
  parser.add_argument("-si", "--simulator", type=str, default="vcs",
                      help="Simulator used to run the generator, default VCS", dest="simulator")
  • -si--simulator: 用于运行生成器的模拟器,默认值为 vcs
  parser.add_argument("--iss", type=str, default="spike",
                      help="RISC-V instruction set simulator: spike,ovpsim,sail")
  • --iss: RISC-V 指令集模拟器,默认值为 spike
  parser.add_argument("-v", "--verbose", dest="verbose", action="store_true", default=False,
                      help="Verbose logging")
  • -v--verbose: 启用详细日志记录。
  parser.add_argument("--co", dest="co", action="store_true", default=False,
                      help="Compile the generator only")
  • --co: 仅编译生成器。
  parser.add_argument("--cov", dest="cov", action="store_true", default=False,
                      help="Enable functional coverage")
  • --cov: 启用功能覆盖率。
  parser.add_argument("--so", dest="so", action="store_true", default=False,
                      help="Simulate the generator only")
  • --so: 仅模拟生成器。
  parser.add_argument("--cmp_opts", type=str, default="",
                      help="Compile options for the generator")
  • --cmp_opts: 生成器的编译选项,默认值为空字符串。
  parser.add_argument("--sim_opts", type=str, default="",
                      help="Simulation options for the generator")
  • --sim_opts: 生成器的模拟选项,默认值为空字符串。
  parser.add_argument("--gcc_opts", type=str, default="",
                      help="GCC compile options")
  • --gcc_opts: GCC 编译选项,默认值为空字符串。
  parser.add_argument("--issrun_opts", type=str, default="+debug_disable=1",
                      help="Simulation run options")
  • --issrun_opts: 模拟运行选项,默认值为 +debug_disable=1
  parser.add_argument("--isscomp_opts", type=str, default="",
                      help="Simulation compile options")
  • --isscomp_opts: 模拟编译选项,默认值为空字符串。
  parser.add_argument("--isspostrun_opts", type=str, default="0x0000000080000000",
                      help="Simulation post run options")
  • --isspostrun_opts: 模拟后运行选项,默认值为 0x0000000080000000
  parser.add_argument("-s", "--steps", type=str, default="all",
                      help="Run steps: gen,gcc_compile,iss_sim,iss_cmp", dest="steps")
  • -s--steps: 运行步骤,默认值为 all
  parser.add_argument("--lsf_cmd", type=str, default="",
                      help="LSF command. Run in local sequentially if lsf \
                            command is not specified")
  • --lsf_cmd: LSF 命令。如果未指定 LSF 命令,则在本地顺序运行,默认值为空字符串。
  parser.add_argument("--isa", type=str, default="",
                      help="RISC-V ISA subset")
  • --isa: RISC-V ISA 子集,默认值为空字符串。
  parser.add_argument("--priv", type=str, default="msu",
                      help="RISC-V ISA privilege models")
  • --priv: RISC-V ISA 权限模型,默认值为 msu
  parser.add_argument("-m", "--mabi", type=str, default="",
                      help="MABI used for compilation", dest="mabi")
  • -m--mabi: 用于编译的 MABI,默认值为空字符串。
  parser.add_argument("--gen_timeout", type=int, default=360,
                      help="Generator timeout limit in seconds")
  • --gen_timeout: 生成器超时限制(秒),默认值为 360
  parser.add_argument("--end_signature_addr", type=str, default="0",
                      help="Address that privileged CSR test writes to at EOT")
  • --end_signature_addr: 特权 CSR 测试在结束时写入的地址,默认值为 0
  parser.add_argument("--iss_opts", type=str, default="",
                      help="Any ISS command line arguments")
  • --iss_opts: 任何 ISS 命令行参数,默认值为空字符串。
  parser.add_argument("--iss_timeout", type=int, default=500,
                      help="ISS sim timeout limit in seconds")
  • --iss_timeout: ISS 模拟超时限制(秒),默认值为 500
  parser.add_argument("--iss_yaml", type=str, default="",
                      help="ISS setting YAML")
  • --iss_yaml: ISS 设置 YAML 文件的路径,默认值为空字符串。
  parser.add_argument("--simulator_yaml", type=str, default="",
                      help="RTL simulator setting YAML")
  • --simulator_yaml: RTL 模拟器设置 YAML 文件的路径,默认值为空字符串。
  parser.add_argument("--csr_yaml", type=str, default="",
                      help="CSR description file")
  • --csr_yaml: CSR 描述文件的路径,默认值为空字符串。
  parser.add_argument("-ct", "--custom_target", type=str, default="",
                      help="Directory name of the custom target")
  • -ct--custom_target: 自定义目标的目录名称,默认值为空字符串。
  parser.add_argument("-cs", "--core_setting_dir", type=str, default="",
                      help="Path for the riscv_core_setting.sv")
  • -cs--core_setting_dir: riscv_core_setting.sv 文件的路径,默认值为空字符串。
  parser.add_argument("-ext", "--user_extension_dir", type=str, default="",
                      help="Path for the user extension directory")
  • -ext--user_extension_dir: 用户扩展目录的路径,默认值为空字符串。
  parser.add_argument("--asm_tests", type=str, default="",
                      help="Directed assembly tests")
  • --asm_tests: 定向汇编测试的路径,默认值为空字符串。
  parser.add_argument("--c_tests", type=str, default="",
                      help="Directed c tests")
  • --c_tests: 定向 C 测试的路径,默认值为空字符串。
  parser.add_argument("--elf_tests", type=str, default="",
                      help="Directed elf tests")
  • --elf_tests: 定向 ELF 测试的路径,默认值为空字符串。
  parser.add_argument("--log_suffix", type=str, default="",
                      help="Simulation log name suffix")
  • --log_suffix: 模拟日志名称后缀,默认值为空字符串。
  parser.add_argument("--exp", action="store_true", default=False,
                      help="Run generator with experimental features")
  • --exp: 使用实验功能运行生成器。
  parser.add_argument("-bz", "--batch_size", type=int, default=0,
                      help="Number of tests to generate per run. You can split a big"
                           " job to small batches with this option")
  • -bz--batch_size: 每次运行生成的测试数量,可以使用此选项将大作业拆分为小批次,默认值为 0
  parser.add_argument("--stop_on_first_error", dest="stop_on_first_error",
                      action="store_true", default=False,
                      help="Stop on detecting first error")
  • --stop_on_first_error: 在检测到第一个错误时停止。
  parser.add_argument("--noclean", action="store_true", default=True,
                      help="Do not clean the output of the previous runs")
  • --noclean: 不清理以前运行的输出。
  parser.add_argument("--verilog_style_check", action="store_true", default=False,
                      help="Run verilog style check")
  • --verilog_style_check: 运行 Verilog 风格检查。
  parser.add_argument("-d", "--debug", type=str, default="",
                      help="Generate debug command log file")
  • -d--debug: 生成调试命令日志文件,默认值为空字符串。
  parser.add_argument("--hwconfig_opts", type=str, default="",
                      help="Custom configuration options for util/user_config.py")
  • --hwconfig_opts: util/user_config.py 的自定义配置选项,默认值为空字符串。
  parser.add_argument("-l", "--linker", type=str, default="",
                      help="Path for the link.ld")
  • -l--linker: link.ld 文件的路径,默认值为空字符串。
  parser.add_argument("--axi_active", type=str, default="",
                      help="Switch AXI agent mode: yes for Active, no for Passive")
  • --axi_active: 切换 AXI 代理模式:yes 表示主动,no 表示被动,默认值为空字符串。
  parser.add_argument("--gen_sv_seed", type=int, default=0,
                      help="Run test N times with random seed")
  • --gen_sv_seed: 使用随机种子运行测试 N 次,默认值为 0
  parser.add_argument("--sv_seed", type=str, default=str(random.getrandbits(31)),
                      help="Run test with a specific seed")
  • --sv_seed: 使用特定种子运行测试,默认值为生成的随机种子。
  parser.add_argument("--isa_extension", type=str, default="",
                      help="Choose additional z, s, x extensions")
  • --isa_extension: 选择附加的 z、s、x 扩展,默认值为空字符串。
  parser.add_argument("--spike_params", type=str, default="",
                      help="Spike command line parameters, run spike --help and spike --print-params to see more")
  • --spike_params: Spike 命令行参数,默认值为空字符串。

随机种子参数组

  rsg = parser.add_argument_group('Random seeds',
                                  'To control random seeds, use at most one '
                                  'of the --start_seed, --seed or --seed_yaml '
                                  'arguments. Since the latter two only give '
                                  'a single seed for each test, they imply '
                                  '--iterations=1.')

  rsg.add_argument("--start_seed", type=read_seed,
                   help=("Randomization seed to use for first iteration of "
                         "each test. Subsequent iterations use seeds "
                         "counting up from there. Cannot be used with "
                         "--seed or --seed_yaml."))
  rsg.add_argument("--seed", type=read_seed,
                   help=("Randomization seed to use for each test. "
                         "Implies --iterations=1. Cannot be used with "
                         "--start_seed or --seed_yaml."))
  rsg.add_argument("--seed_yaml", type=str,
                   help=("Rerun the generator with the seed specification "
                         "from a prior regression. Implies --iterations=1. "
                         "Cannot be used with --start_seed or --seed."))
  • 添加一个参数组 Random seeds,用于控制随机种子。
  • 定义 --start_seed--seed--seed_yaml 参数。

参数解析和验证

  args = parser.parse_args()

  if args.seed is not None and args.start_seed is not None:
    logging.error('--start_seed and --seed are mutually exclusive.')
    sys.exit(RET_FAIL)

  if args.seed is not None:
    if args.iterations == 0:
      args.iterations = 1
    elif args.iterations > 1:
      logging.error('--seed is incompatible with setting --iterations '
                    'greater than 1.')
      sys.exit(RET_FAIL)

  return args
  • 解析命令行参数。
  • 验证 --seed--start_seed 参数是否互斥。
  • 如果 --seed 参数存在且 --iterations 为 0,则将 --iterations 设置为 1。
  • 如果 --seed 参数存在且 --iterations 大于 1,则记录错误并退出。

总结

parse_args 函数通过定义命令行参数及其默认值和帮助信息,创建一个命令行参数解析器,并解析和验证输入参数。返回解析后的参数对象 args

你可能感兴趣的:(core-v-verif)