提示:这篇文章即将在作者的博客上发布,敬请期待。
CO_tester
repo: https://github.com/FyVoid/BUAA_CO_tester 北航云盘提供的下载存在严重的bug,且难以随后续开发更新,现只提供github repo地址
本项目包括
- python实现的MIPS汇编程序生成程序
- 一套利用mars命令行和iverilog对随机生成的程序进行汇编、仿真并输出结果的流程
- 可自定义的汇编指令生成、有一定扩展性
- 通过魔改版MARS进行正确性验证
环境配置
完整运行此测试流程,你需要至少有
- iverilog
- java(支持mars)
- shell脚本支持(windows可以尝试使用git bash)
如果要通过gtkwave查看波形,则需要安装gtkwave并支持控制台命令gtkwave
太长不看
clone或从北航云盘下载后,将CO_tester和你的verilog源代码置于同一个目录,将verilog源码(应该包含一个能正常运行的testbench)置于src文件夹下,此时目录应该类似于:
1 | . |
在终端运行
1 | sh CO_test.sh |
程序会自动生成一个mips程序assemble.asm
mars命令行会将该程序转化为code.txt,随后iverilog会编译verilog源码,并生成波形和cpu输出(存于cpu_output.txt),python程序会对比verilog输出和魔改版MARS产生的标准输出,输出对应关系于log.txt,gtkwave会自动启动并显示波形
log.txt应该类似这样
1 | @00003000: $18 <= 29a30000 <=> @00003000: $18 <= 29a30000 |
整个测试逻辑图如下,各个组件可以分开使用
批量测试
愿意折腾的学生能学到更多
如果你去github上获取最新版,可以通过
1 | sh batch_test.sh <batch_count> |
进行批量测试,如果不指定batch_count,则会进行50次测试
测试的结果会被汇总到batch_log.txt文件下
高级功能
事实上,你可以通过一定的修改来自定义汇编程序的生成,可以自定义的部分包括
- 自定义新指令
- 自定义每个指令生成概率
- 自定义某些行为的概率(如跳转和内存存取)
- 自定义生成程序的指令条数
自定义新指令
通过调整tester_config.txt的内容,你可以减少/添加已有的指令,控制每个指令生成的概率,甚至自定义新的指令
指令的格式为
1 | [指令名] [参数1], (参数2), (参数3) | (output), (prob:生成概率) |
指令名可以是任何合理的名字
参数可选的值如下
参数 | 效果 |
---|---|
$reg | 随机产生\$t, \$s, \$a, \$v中的寄存器 |
$t | 随机产生\$t0-\$t9 |
$s | 随机产生\$s0-\$s7 |
$a | 随机产生\$a0-\$a3 |
$v | 随机产生\$v0 or \$v1 |
$im | 随机产生范围为0-0xffff的立即数 |
$lb | 随机产生跳转标签、标签可能是已经存在的标签,也可能是新的标签,这个概率由generate.py中的参数决定 |
$rega | 随机产生一个形如offset(\$t0)的地址,地址的值(即offset+\$t0)可能是先前使用过的地址,也可能是新的地址,如果是已经产生过的地址,则一定为0(\$t0) |
$rega
一定会在存取指令前产生一条ori
指令,保证地址对齐
指令结尾的|
是必须的,如果其后有output
,表示该条指令会导致verilog仿真产生输出(根据CO课程规则),如果有prob
,表示该指令的概率人为制定,格式为prob:(0-1的数)f
,结尾的f
是必须的
如果所有指令概率和>1或所有指令概率和<=1且每条指令均被指定概率,则每条指令概率为该条指令概率/总概率
否则,未指定概率指令概率为(1-已指定指令概率和)/(未指定概率指令数)
自定义生成概率和生成数量
generate.py文件中
1 | gen_label_prob = 0.2 # 产生新标签的概率 |
shell脚本命令行参数
- nw: 不自动开启gtkwave
- nl: log中不保存所有指令对应关系
- ns: 命令行不输出log
- dir <dirname>: 保存临时文件和log的目录
最后
现在采用学长开发的魔改版MARS生成
github版本已经更新批量测试版本
该自动化程序会继续更新适用新的课程要求
同学你好,感谢你将自己的在测试方面的成果开源分享供大家学习。目前的程序已经基本具有了在 verilog cpu 中进行自动化测试的能力了。下面是一些小小的改进意见,希望能够帮助同学进一步完善自动化测试的流程。
- 首先,在测试代码生成部分,预先设置 tester_config 文件将待测指令的格式进行统计是一种很巧妙的方法,直观地将程序的代码量进行了缩减。但在后续 project 中,我们构建的 cpu 需要支持更多的指令类和具体指令,只用文本的方式对指令的特征进行说明、区分可能会略显吃力。可以尝试对指令类、单条指令进行建类、继承,对指令进行更详细的区分,也能更好地控制指令所用寄存器、立即数的选用策略。
- 其次,不知你是否注意到了,在同学提供的 log.txt 中,3条 add、sub 指令,其中有 2 条实际上进行了对两个内容为 0 寄存器的运算,如果同学后续有继续改进的想法,在测试强度上可以从这一点入手进行改进。
- 最后,对于进行仿真的工具链,可以尝试使用 ise 的命令行工具进行仿真,我们的教程中也有相关的章节。不过可能会多增加一些用户使用时的配置步骤,但同样在教程中有提示:
最终仿真的结果依旧以 ISE 为准,Icarus Verilog 在某些情况下会与 ISE 产生不同结果。
希望完善后的测试工具能够帮助更多的同学
All Correct Nya!
感谢助教的指正
其实采取配置文件定义指令的设计模式是出于以下考虑
- tester只负责指令的文本生成
- mars负责所有的指令实际译码和执行
也就是希望通过隔离指令文本的生成和解释两个部分提供更加便捷、可扩展性更高的测试过程,例如如果我想加入qaq指令,只需要在config中加入
1 | qaq $reg, $reg, $reg | |
而qaq指令具体的执行依赖于mars相关的修改,例如采用学长开发的魔改版mars添加class文件扩展
当然,未来如果已有的指令格式不足以表达需求,也会增加新的指令格式
另外感谢提出出现重复无用测试的情况,会想办法改进!
学长有写过一个魔改版mars,可以拿来当std用https://github.com/Toby-Shi-cloud/Mars-with-BUAA-CO-extension
如果有人在.v文件中写了`include,需要在compile.sh中将
1 | find ../src -name "*.v" | xargs iverilog -o wave |
改为
1 | find ../src -name "*.v" | xargs iverilog -o wave -I <include files path> |
以支持.v文件中的`include。
例如include都在同一层文件夹下,include files path
就为../src
。
gen似乎是有一点问题,可能在存取数据的时候没判范围之类的,跑mars的时候有个报错
1 | line 17: Runtime exception at 0x00003038: address out of range 0xffffff44 |
vvp运行的时候似乎不能停止?我跑的时候有这个问题,所以给前面加上了一个timeout 1
。不知道楼主有没有这个问题。