IBEX系列之Verification学习笔记之metadata 代码路径main函数def_main():parserargparse.ArgumentParser()parser.add_argument(--op,typeOps,choicesOps,requiredTrue)parser.add_argument(--dir-metadata,typepathlib.Path,requiredTrue)parser.add_argument(--dir-out,typepathlib.Path,requiredFalse)parser.add_argument(--args-list,typestr,requiredFalse)parser.add_argument(--field,typestr,requiredFalse)argsparser.parse_args()ifargs.opOps.CREATE:if(pathlib.Path(args.dir_metadata)/metadata.pickle).exists():logger.error(Build metadata already exists, not recreating from scratch.)returnmdRegressionMetadata.arg_list_initializer(dir_metadataargs.dir_metadata,dir_outargs.dir_out,git_commitget_git_revision_hash(),args_listargs.args_list)md._get_ibex_metadata()md.tests_and_countsmd.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.seedcount):tds_strf{test}.{testseed}trrTestRunResult(passedNone,failure_messageNone,testtypetesttype,testdotseedtds_str,testnametest,seedtestseed,rtl_simulatormd.simulator,iss_cosimmd.iss,dir_testmd.dir_tests/tds_str,metadata_pickle_filemd.pickle_file,pickle_filemd.dir_metadata/(tds_str.pickle),yaml_filemd.dir_tests/tds_str/trr.yaml)iftesttypeTestType.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_yamlTrue)md.export(write_yamlTrue)ifargs.opOps.PRINT_FIELD:mdRegressionMetadata.construct_from_metadata_dir(args.dir_metadata)if(args.fieldriscvdv_tds):tds_list[]fortest,count,testtypeinmd.tests_and_counts:fortestseedinrange(md.seed,md.seedcount):iftesttypeTestType.RISCVDV:tds_list.append(f{test}.{testseed})print( .join(tds_list))returnif(args.fielddirected_tds):tds_list[]fortest,count,testtypeinmd.tests_and_counts:fortestseedinrange(md.seed,md.seedcount):iftesttypeTestType.DIRECTED:tds_list.append(f{test}.{testseed})print( .join(tds_list))returnvaluegetattr(md,args.field)ifvalueisNone:raiseRuntimeError(Field requested is not present or not set in the regression metadata object)logger.debug(fReturning value of field{args.field}as{value})print(str(value))main函数在metadata.py文件中解析命令行参数并基于指定的操作执行相应任务。以下是其主要步骤解析命令行参数:--op: 指定操作类型值为Ops枚举中的一个CREATE或PRINT_FIELD。--dir-metadata: 指定存储构建元数据的目录。--dir-out: 可选参数指定回归构建和测试进行的目录。--args-list: 可选参数输入形式为KEYVALUE KEY2VALUE2的字符串。--field: 可选参数当操作为PRINT_FIELD时指定要打印的字段。执行操作: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操作。这段代码的主要功能是根据传入的参数创建一个新的元数据对象并设置相关的回归测试配置。详细分析如下检查现有元数据:检查metadata.pickle文件是否存在于--dir-metadata指定的目录中。如果存在记录错误信息并返回不会重新创建元数据。初始化元数据对象:调用RegressionMetadata.arg_list_initializer方法传入dir_metadata、dir_out、git_commit和args_list参数初始化一个新的RegressionMetadata对象。git_commit通过get_git_revision_hash方法获取当前的 Git 提交哈希值。args_list是一个KEYVALUE KEY2VALUE2形式的字符串用于传递初始化参数。获取 Ibex 特定的元数据:调用md._get_ibex_metadata方法获取更多派生的 Ibex 特定元数据。设置测试和计数:调用md.get_tests_and_counts方法解析riscv-dv和directed-test结构化数据例如testlist.yaml和directed_testlist.yaml设置要运行的测试及其计数。如果md.tests_and_counts为空抛出运行时错误。设置每个测试的元数据对象:遍历md.tests_and_counts中的测试和计数为每个测试创建一个TestRunResult对象。对于每个测试的每个计数生成test.seed字符串例如test.1、test.2等。初始化TestRunResult对象传入相关参数包括测试类型、测试名称、种子、模拟器、协同仿真等。如果测试类型是DIRECTED从directed_test_schema中获取构建命令所需的数据。将每个TestRunResult对象的路径添加到md.tests_pickle_files列表中。将TestRunResult对象导出到磁盘。导出元数据对象:调用md.export方法将新的RegressionMetadata对象导出保存到磁盘。ifargs.opOps.CREATE:if(pathlib.Path(args.dir_metadata)/metadata.pickle).exists():logger.error(Build metadata already exists, not recreating from scratch.)returnmdRegressionMetadata.arg_list_initializer(dir_metadataargs.dir_metadata,dir_outargs.dir_out,git_commitget_git_revision_hash(),args_listargs.args_list)md._get_ibex_metadata()md.tests_and_countsmd.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.seedcount):tds_strf{test}.{testseed}trrTestRunResult(passedNone,failure_messageNone,testtypetesttype,testdotseedtds_str,testnametest,seedtestseed,rtl_simulatormd.simulator,iss_cosimmd.iss,dir_testmd.dir_tests/tds_str,metadata_pickle_filemd.pickle_file,pickle_filemd.dir_metadata/(tds_str.pickle),yaml_filemd.dir_tests/tds_str/trr.yaml)iftesttypeTestType.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_yamlTrue)md.export(write_yamlTrue)PRINT_FIELD操作这段代码处理PRINT_FIELD操作用于从构建元数据对象中打印特定字段的值。详细分析如下构建元数据对象:调用RegressionMetadata.construct_from_metadata_dir方法从--dir-metadata指定的目录中构建元数据对象md。处理特殊字段:检查--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字符串打印出来。获取并打印字段值:使用getattr函数获取md对象中指定字段的值。如果值为None抛出运行时错误提示该字段不存在或未设置。记录调试信息打印字段值。ifargs.opOps.PRINT_FIELD:mdRegressionMetadata.construct_from_metadata_dir(args.dir_metadata)if(args.fieldriscvdv_tds):tds_list[]fortest,count,testtypeinmd.tests_and_counts:fortestseedinrange(md.seed,md.seedcount):iftesttypeTestType.RISCVDV:tds_list.append(f{test}.{testseed})print( .join(tds_list))returnif(args.fielddirected_tds):tds_list[]fortest,count,testtypeinmd.tests_and_counts:fortestseedinrange(md.seed,md.seedcount):iftesttypeTestType.DIRECTED:tds_list.append(f{test}.{testseed})print( .join(tds_list))returnvaluegetattr(md,args.field)ifvalueisNone:raiseRuntimeError(Field requested is not present or not set in the regression metadata object)logger.debug(fReturning value of field{args.field}as{value})print(str(value))RegressionMetadataRegressionMetadata类用于管理和存储与 Ibex 核心回归测试相关的元数据。这个类包含了多个属性和方法以下是详细解释类的属性dir_out和dir_metadata输出目录和元数据目录路径。git_commitGit 提交哈希。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_issISA 配置。run_rtl_timeout_sRTL 运行超时时间。各种文件路径如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分支主要用于创建新的元数据对象并将其导出到磁盘。以下是详细的步骤分析解析命令行参数使用argparse模块解析命令行参数其中包括操作类型--op、元数据目录--dir-metadata、输出目录--dir-out和参数列表--args-list。检查元数据文件是否存在如果元数据文件metadata.pickle已经存在则输出错误信息并终止操作避免重复创建。初始化元数据对象调用RegressionMetadata.arg_list_initializer方法从参数列表初始化元数据对象。该方法将参数字符串解析成键值对并根据类定义中的字段类型进行类型转换。初始化后的对象包含构建和测试的所有配置参数。获取 Ibex 配置调用md._get_ibex_metadata()方法获取 Ibex 的特定配置参数并进行必要的检查如迭代次数和种子值的合法性。设置测试和迭代次数调用md.get_tests_and_counts()方法解析 riscvdv 和定向测试的测试列表生成测试名称和迭代次数的列表。初始化每个测试的元数据对象对于每个测试和对应的迭代次数生成TestRunResult对象包含测试的详细信息如测试类型、种子值、仿真器等。如果是定向测试从定向测试 yaml 文件中获取测试数据。将每个测试的元数据对象路径保存到md.tests_pickle_files列表中并将对象导出到磁盘。导出元数据对象最后将整个RegressionMetadata对象导出到磁盘保存为 pickle 和 yaml 文件。通过上述步骤CREATE分支确保了所有构建和测试的元数据能够被正确初始化和存储为后续的回归测试提供必要的配置和数据支持。