本文
主要介绍一个基于Python实现的ARM随机指令生成器。
版本 | 说明 |
---|---|
0.1 | 初版发布 |
背景
在CPU验证中,出于各种原因,经常需要通过汇编程序来实现定向测试,不管是TOP验证环境还是UT验证环境,都有这样的需求。
通过elf作为CPU验证的激励是一个很好的选择,通过已有的高质量测试集合可以有效的保证验证质量,比如ARM Raven测试集。但是对于UT验证或TOP验证的某些场景下需要手写汇编程序作为激励输入,手写汇编的方式提高了灵活性,可以定向测试某些场景,但是毕竟产能有限,且不好保证测试质量。
基于上述背景,所以基于Python实现了ARM随机指令生成器。
功能
支持指令集合中随机选取指令组成测试程序,并且单条指令支持以下字段的随机:
# <id> : 整型寄存器编号d
# <in> : 整型寄存器编号n
# <im> : 整型寄存器编号m
# <ia> : 整型寄存器编号a
# <fd> : 浮点寄存器编号d
# <fn> : 浮点寄存器编号n
# <fm> : 浮点寄存器编号m
# <fa> : 浮点寄存器编号a
# <T1> : 向量处理类型1
# <T2> : 向量处理类型2
# <V> : 浮点寄存器类型(H/S/D)
# <R> : 整型寄存器类型(X/W)
# <index> : element索引值
目前仅支持这些随机字段,本文目的不是提供一个完整功能的随机指令生成器,而是展示一个框架,方便使用者自定义一些功能。
文件结构
├── A64_TPL.list
├── A32_TPL.list
├── T32_TPL.list
├── gen_testcode.py
├── src
│ ├── Function.py
│ ├── SuperTPL.py
│ └── TPL
│ ├── TPL_demo1.py
│ ├── TPL_demo2.py
└── tools
Function.py文件
Function.py文件是一个函数集合:(TPL指template)
- add_TPL(TPL):将某指令TPL添加到TPL_list,作为一个指令集合,便于从中随机选取指令,组合成测试程序。
- get_random_TPL():从TPL_list随机选取一条指令TPL。
- gen_testinstr_codeblock(test_depend):从指令集合中随机抽取100次,组成100条指令的测试程序,这里test_depend为1,会缩小寄存器编号的随机范围,提高指令间依赖的概率。
- gen_cfgfreg_codeblock_a64(random_data_list):从random_data_list中随机选取数据来更新浮点寄存器,通过此方法更新操作数可提高测试质量。
- gen_cfgfreg_codeblock_a32(random_data_list)、gen_cfgfreg_codeblock_t32(random_data_list)同上。
- gen_cfggreg_codeblock_a64(random_data_list):从random_data_list中随机选取数据来更新整型寄存器,通过此方法更新操作数可提高测试质量。
- gen_cfggreg_codeblock_a32(random_data_list):、gen_cfggreg_codeblock_t32(random_data_list)同上。
- gen_cfgfpcr_codeblock_a64():产生合法的随机数据,配置浮点控制寄存器,目的是覆盖更多的随机场景。
- gen_cfgfpcr_codeblock_a32()、gen_cfgfpcr_codeblock_t32()同上。
|
|
SuperTPL.py文件
SuperTPL.py文件是每个指令TPL的父类,定义了基础的变量和函数。主要内容如下:
- 定义各字段的随机范围(属于默认值)。
- 设置test_depend下的寄存器编号字段随机范围。
- 设置非A64下的寄存器编号字段随机范围。
- 各个字段的随机范围重新定义函数(为子类的个性化设置提供方法)。
- 各个字段的获取随机值函数。
- gen_one_instr(self)函数:生成一条指令,主要对指令TPL的各个字段进行随机值替换。
|
|
TPL下的文件
TPL下的文件是指令的模板,继承自SuperTPL.py。以下指令模板仅为展示所用,不代表ARM合法指令。
|
|
xx_TPL.list文件
xx_TPL.list是src/TPL/目录下的集合清单,罗列了单个TPL名称,也对多个TPL进行了分组,供gen_testcode.py使用。
注意:对于单个TPL文件的组织,可以定义单条指令及它的多种变型,也可以定义多条指令,具体粒度由使用者灵活掌握。这里建议一个TPL定义一组同类型指令,比如浮点双精度加法运算。
casename=TPL_demo1, groupname=demo
casename=TPL_demo2, groupname=demo
gen_testcode.py文件
gen_testcode.py文件是整个环境的top脚本。提供的使用参数如下:
- args_ISA :设置生成的指令类型,A64 or A32 or T32
- args_filename :设置输出文件名称
- args_casename :设置随机的TPL名称(不可与groupname同时设置)
- args_groupname :设置随机的多个TPL组合名称(不可与casename同时设置)
- args_testfloat :设置是否使用testfloat数据更新浮点寄存器,可选参数为FP64、FP32、FP16(此环境暂时没集成testfloat,不可设置),如果不设置默认使用随机值。
- args_sizelevel :设置sizelevel(默认为1),生成的测试指令数等于 sizelevel*100 + cfgfreg_instrnum…
- args_cfgfpcr :设置支持fpcr寄存器配置(在每100条测试指令前配置)
- args_seednum :设置随机种子,随机种子会注释到输出文件首行,目的是支持可复现性。
- args_test_depend :设置支持test_depend,如果测试指令依赖,会将寄存器编号的随机范围缩小。
|
|
tools目录
tools目录下是为了集成testfloat或其他应用程序而提供的,暂时未集成testfloat。
使用方法
- 首先参考/src/TPL/TPL_demo1.py文件,定义新的指令类型,对于随机字段的随机范围可重新定义,也可以使用默认范围。
- 如果有环境中未支持的随机字段,需要在SuperTPL.py文件添加相关操作,包括定义随机范围、获取随机值、随机字段替换等。
- 将TPL添加至对应的xx_TPL.list,casename与TPL文件名称保持一致,groupnamename可自定义。
- 使用gen_testcode.py脚本生成随机指令,具体gen_testcode.py的使用方法和参数可以通过-h获取。
- 对于生成随机指令的合法性,需要通过ARM编译器进行检验,成功编译说明TPL没问题,成熟的TPL可能需要经过多次检验。
文章原创,可能存在部分错误,欢迎指正,联系邮箱 cao_arvin@163.com。