☰
IBEX系列之Verification学习笔记之metadata
2026/10/27 18:21:39 网站建设 项目流程

代码路径

main函数

def_main():parser=argparse.ArgumentParser()parser.add_argument('--op',type=Ops,choices=Ops,required=True)parser.add_argument('--dir-metadata',type=pathlib.Path,required=True)parser.add_argument('--dir-out',type=pathlib.Path,required=False)parser.add_argument('--args-list',type=str,required=False)parser.add_argument('--field',type=str,required=False)args=parser.parse_args()ifargs.op==Ops.CREATE:if(pathlib.Path(args.dir_metadata)/'metadata.pickle').exists():logger.error("Build metadata already exists, not recreating from scratch.")returnmd=RegressionMetadata.arg_list_initializer(dir_metadata=args.dir_metadata,dir_out=args.dir_out,git_commit=get_git_revision_hash(),args_list=args.args_list)md._get_ibex_metadata()md.tests_and_counts=md.get_tests_and_counts()ifnotmd.tests_and_counts:raiseRuntimeError("md.tests_and_counts is empty, cannot get TEST.SEED strings.")fortest,count,testtypeinmd.tests_and_counts:fortestseedinrange(md.seed,md.seed+count):tds_str=f"{test}.{testseed}"trr=TestRunResult(passed=None,failure_message=None,testtype=testtype,testdotseed=tds_str,testname=test,seed=testseed,rtl_simulator=md.simulator,iss_cosim=md.iss,dir_test=md.dir_tests/tds_str,metadata_pickle_file=md.pickle_file,pickle_file=md.dir_metadata/(tds_str+".pickle"),yaml_file=md.dir_tests/tds_str/'trr.yaml')iftesttype==TestType.DIRECTED:trr.directed_data=(next(filter(lambdai:i['test']==test,directed_test_schema.import_model(md.directed_test_data).get('tests'))))md.tests_pickle_files.append(trr.pickle_file)trr.export(write_yaml=True)md.export(write_yaml=True)ifargs.op==Ops.PRINT_FIELD:md=RegressionMetadata.construct_from_metadata_dir(args.dir_metadata)if(args.field=='riscvdv_tds'):tds_list=[]fortest,count,testtypeinmd.tests_and_counts:fortestseedinrange(md.seed,md.seed+count):iftesttype==TestType.RISCVDV:tds_list.append(f"{test}.{testseed}")print(" ".join(tds_list))returnif(args.field=='directed_tds'):tds_list=[]fortest,count,testtypeinmd.tests_and_counts:fortestseedinrange(md.seed,md.seed+count):iftesttype==TestType.DIRECTED:tds_list.append(f"{test}.{testseed}")print(" ".join(tds_list))returnvalue=getattr(md,args.field)ifvalueisNone:raiseRuntimeError("Field requested is not present or not set in the regression metadata object")logger.debug(f"Returning value of field{args.field}as{value}")print(str(value))

main函数在metadata.py文件中解析命令行参数并基于指定的操作执行相应任务。以下是其主要步骤:

  1. 解析命令行参数:

    • --op: 指定操作类型,值为Ops枚举中的一个(CREATE或PRINT_FIELD)。
    • --dir-metadata: 指定存储构建元数据的目录。
    • --dir-out: 可选参数,指定回归构建和测试进行的目录。
    • --args-list: 可选参数,输入形式为'KEY=VALUE KEY2=VALUE2'的字符串。
    • --field: 可选参数,当操作为PRINT_FIELD时指定要打印的字段。
  2. 执行操作:

    • CREATE:

      • 检查metadata.pickle文件是否已存在,若存在则记录错误信息并退出。
      • 调用RegressionMetadata.arg_list_initializer初始化元数据对象,传入必要参数。
      • 调用_get_ibex_metadata获取更多派生的 Ibex 特定元数据。
      • 调用get_tests_and_counts设置要使用的测试及其计数。
      • 将每个测试对象保存到磁盘并将其路径添加到tests_pickle_files列表中。
      • 将新建的RegressionMetadata对象导出保存到磁盘。
    • PRINT_FIELD:

      • 调用RegressionMetadata.construct_from_metadata_dir从元数据目录构造元数据对象。
      • 根据--field参数打印相应字段的值。如果字段包含测试的列表,则分别处理并打印测试的test.seed字符串。

CREATE操作

这部分代码是main函数中的一个分支,用于处理CREATE操作。这段代码的主要功能是根据传入的参数创建一个新的元数据对象,并设置相关的回归测试配置。详细分析如下:

  1. 检查现有元数据:

    • 检查metadata.pickle文件是否存在于--dir-metadata指定的目录中。如果存在,记录错误信息并返回,不会重新创建元数据。
  2. 初始化元数据对象:

    • 调用RegressionMetadata.arg_list_initializer方法,传入dir_metadata、dir_out、git_commit和args_list参数,初始化一个新的RegressionMetadata对象。
    • git_commit通过get_git_revision_hash方法获取当前的 Git 提交哈希值。
    • args_list是一个'KEY=VALUE KEY2=VALUE2'形式的字符串,用于传递初始化参数。
  3. 获取 Ibex 特定的元数据:

    • 调用md._get_ibex_metadata方法,获取更多派生的 Ibex 特定元数据。
  4. 设置测试和计数:

    • 调用md.get_tests_and_counts方法,解析riscv-dv和directed-test结构化数据(例如testlist.yaml和directed_testlist.yaml),设置要运行的测试及其计数。
    • 如果md.tests_and_counts为空,抛出运行时错误。
  5. 设置每个测试的元数据对象:

    • 遍历md.tests_and_counts中的测试和计数,为每个测试创建一个TestRunResult对象。
    • 对于每个测试的每个计数,生成test.seed字符串(例如test.1、test.2等)。
    • 初始化TestRunResult对象,传入相关参数,包括测试类型、测试名称、种子、模拟器、协同仿真等。
    • 如果测试类型是DIRECTED,从directed_test_schema中获取构建命令所需的数据。
    • 将每个TestRunResult对象的路径添加到md.tests_pickle_files列表中。
    • 将TestRunResult对象导出到磁盘。
  6. 导出元数据对象:

    • 调用md.export方法,将新的RegressionMetadata对象导出保存到磁盘。
ifargs.op==Ops.CREATE:if(pathlib.Path(args.dir_metadata)/'metadata.pickle').exists():logger.error("Build metadata already exists, not recreating from scratch.")returnmd=RegressionMetadata.arg_list_initializer(dir_metadata=args.dir_metadata,dir_out=args.dir_out,git_commit=get_git_revision_hash(),args_list=args.args_list)md._get_ibex_metadata()md.tests_and_counts=md.get_tests_and_counts()ifnotmd.tests_and_counts:raiseRuntimeError("md.tests_and_counts is empty, cannot get TEST.SEED strings.")fortest,count,testtypeinmd.tests_and_counts:fortestseedinrange(md.seed,md.seed+count):tds_str=f"{test}.{testseed}"trr=TestRunResult(passed=None,failure_message=None,testtype=testtype,testdotseed=tds_str,testname=test,seed=testseed,rtl_simulator=md.simulator,iss_cosim=md.iss,dir_test=md.dir_tests/tds_str,metadata_pickle_file=md.pickle_file,pickle_file=md.dir_metadata/(tds_str+".pickle"),yaml_file=md.dir_tests/tds_str/'trr.yaml')iftesttype==TestType.DIRECTED:trr.directed_data=(next(filter(lambdai:i['test']==test,directed_test_schema.import_model(md.directed_test_data).get('tests'))))md.tests_pickle_files.append(trr.pickle_file)trr.export(write_yaml=True)md.export(write_yaml=True)

PRINT_FIELD操作

这段代码处理PRINT_FIELD操作,用于从构建元数据对象中打印特定字段的值。详细分析如下:

  1. 构建元数据对象:

    • 调用RegressionMetadata.construct_from_metadata_dir方法,从--dir-metadata指定的目录中构建元数据对象md。
  2. 处理特殊字段:

    • 检查--field参数是否为riscvdv_tds或directed_tds。
    • 如果是riscvdv_tds,遍历md.tests_and_counts列表,筛选出TestType.RISCVDV类型的测试,并生成test.seed字符串(例如test.1、test.2等)。将这些字符串组成的列表打印出来。
    • 如果是directed_tds,类似地,筛选出TestType.DIRECTED类型的测试,并生成test.seed字符串,打印出来。
  3. 获取并打印字段值:

    • 使用getattr函数获取md对象中指定字段的值。
    • 如果值为None,抛出运行时错误,提示该字段不存在或未设置。
    • 记录调试信息,打印字段值。
ifargs.op==Ops.PRINT_FIELD:md=RegressionMetadata.construct_from_metadata_dir(args.dir_metadata)if(args.field=='riscvdv_tds'):tds_list=[]fortest,count,testtypeinmd.tests_and_counts:fortestseedinrange(md.seed,md.seed+count):iftesttype==TestType.RISCVDV:tds_list.append(f"{test}.{testseed}")print(" ".join(tds_list))returnif(args.field=='directed_tds'):tds_list=[]fortest,count,testtypeinmd.tests_and_counts:fortestseedinrange(md.seed,md.seed+count):iftesttype==TestType.DIRECTED:tds_list.append(f"{test}.{testseed}")print(" ".join(tds_list))returnvalue=getattr(md,args.field)ifvalueisNone:raiseRuntimeError("Field requested is not present or not set in the regression metadata object")logger.debug(f"Returning value of field{args.field}as{value}")print(str(value))

RegressionMetadata

RegressionMetadata类用于管理和存储与 Ibex 核心回归测试相关的元数据。这个类包含了多个属性和方法,以下是详细解释:

类的属性:

  • dir_out和dir_metadata:输出目录和元数据目录路径。
  • git_commit:Git 提交哈希。
  • creation_datetime:创建时间。
  • pickle_file和yaml_file:存储元数据的文件路径。
  • raw_args_str和raw_args_dict:构造函数传入的参数字符串和字典。
  • seed、waves、cov、cosim、simulator、iss、test、verbose、iterations、signature_addr、ibex_config、dut_cov_rtl_path:构建和测试相关的配置参数。
  • tests_and_counts:测试和迭代次数的列表。
  • isa_ibex和isa_iss:ISA 配置。
  • run_rtl_timeout_s:RTL 运行超时时间。
  • 各种文件路径:如ibex_configs、ibex_riscvdv_simulator_yaml、ibex_riscvdv_customtarget、ibex_riscvdv_testlist等。
  • 构建日志和命令:如riscvdv_build_log、riscvdv_build_stdout、riscvdv_build_cmds等。
  • 环境变量:environment_variables。
  • 各种项目目录:如ibex_root、riscvdv_root、ot_lowrisc_ip等。

类的方法:

  • __post_init__:初始化后设置相关路径和环境变量。
  • _setup_directories:设置目录变量。
  • _get_ibex_metadata:获取 Ibex 配置参数。
  • arg_list_initializer:从输入字符串初始化字段,返回一个RegressionMetadata对象。
  • construct_from_metadata_dir:从元数据目录构造元数据对象。
  • get_tests_and_counts:获取测试和迭代次数的列表。
  • process_riscvdv_testlist:从 riscvdv 测试列表提取测试信息。
  • process_directed_testlist:从定向测试列表提取测试信息。

使用场景:

  • 在_main()函数中,根据命令行参数执行创建新元数据或打印特定字段的操作。
  • 通过arg_list_initializer方法从参数字符串创建元数据对象。
  • 通过_get_ibex_metadata方法获取 Ibex 的特定配置。
  • 通过get_tests_and_counts方法设置要运行的测试列表。

这个类集中管理与回归测试相关的所有元数据,确保构建过程中的各个配置和测试参数能够被正确初始化和使用。

main函数中的CREATE分支数据流

main函数中的CREATE分支主要用于创建新的元数据对象并将其导出到磁盘。以下是详细的步骤分析:

  1. 解析命令行参数:

    • 使用argparse模块解析命令行参数,其中包括操作类型(--op)、元数据目录(--dir-metadata)、输出目录(--dir-out)和参数列表(--args-list)。
  2. 检查元数据文件是否存在:

    • 如果元数据文件metadata.pickle已经存在,则输出错误信息并终止操作,避免重复创建。
  3. 初始化元数据对象:

    • 调用RegressionMetadata.arg_list_initializer方法,从参数列表初始化元数据对象。该方法将参数字符串解析成键值对,并根据类定义中的字段类型进行类型转换。
    • 初始化后的对象包含构建和测试的所有配置参数。
  4. 获取 Ibex 配置:

    • 调用md._get_ibex_metadata()方法,获取 Ibex 的特定配置参数,并进行必要的检查(如迭代次数和种子值的合法性)。
  5. 设置测试和迭代次数:

    • 调用md.get_tests_and_counts()方法,解析 riscvdv 和定向测试的测试列表,生成测试名称和迭代次数的列表。
  6. 初始化每个测试的元数据对象:

    • 对于每个测试和对应的迭代次数,生成TestRunResult对象,包含测试的详细信息(如测试类型、种子值、仿真器等)。
    • 如果是定向测试,从定向测试 yaml 文件中获取测试数据。
    • 将每个测试的元数据对象路径保存到md.tests_pickle_files列表中,并将对象导出到磁盘。
  7. 导出元数据对象:

    • 最后,将整个RegressionMetadata对象导出到磁盘,保存为 pickle 和 yaml 文件。

通过上述步骤,CREATE分支确保了所有构建和测试的元数据能够被正确初始化和存储,为后续的回归测试提供必要的配置和数据支持。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询