
「BUAA CO」计组小白的自动化测试

关于iverilog和verilog的自动化测试
从P4开始的CPU搭建全部是使用Verilog语言来实现的,使用iverilog进行轻量自动化测试还是很方便的。需要注意的是,考试用的虚拟机有python
和gcc
,但是没有iverilog
vvp
gtkwave
,windows
中也没有。
下面以P4为例,简单介绍一下自动化测试的方式,以避免像我这样的计组小白走弯路。下面使用的是22级计组官方debian虚拟机进行自动化测试。windows与之类似。
假设写好的测试文件名为test.asm
。
但如果你是一个希望探索计组的小白,那还是建议自己搭建自动化测评装置。
用MARS输出标准答案
标准MARS无法使用命令行在运行过程中对寄存器或者内存进行监视,建议自行寻找解决方案,比如自己魔改MARS或者写一个自动化仿真程序
Folding 但是如果改不了一点...
可以使用Toby学长改好的MARS,链接
将下载的文件重命名为mars.jar
,并放在和test.asm文件相同的文件夹下,在该目录的终端下运行:
1 | $ java -jar mars.jar mc CompactLargeText coL1 test.asm > mars_tmp.txt |
这会将mars运行test.asm的正确结果连通mars的输出信息重定向写入mars_tmp.txt文件中。文件除了包含正确输出以外,还包含Mars的输出信息。因此需要在后续步骤中对格式进行检查。这我们在后面再说。
用MARS输出机器码
标准Mars、魔改Mars和课程组官方Mars都能实现这一点,只需要运行
1 | $ java -jar mars.jar dump .text HexText code.txt mc CompactLargeText test.asm |
就会在本地生成一个code.txt文件
用iverilog对CPU进行仿真
下面是关于如何实现在有正确输出结果的情况下,将CPU的输出结果输出到文本文件中。
1. 安装iverilog和vvp
打开Debian终端,或者在Debian虚拟机中按下Win
+R
键,在其中输入:
1 | $ sudo apt-get install iverilog |
这会安装iverilog
以及vvp
。iverilog
是用于对verilog
进行仿真的工具,其中iverilog
能够对verilog
进行编译,而vvp
能够对编译出来的结果进行仿真。可以理解为前者编译后者运行。
2. 编写testbench
在testbench的initial语句块的结束写上# [仿真时长] $finish;
告诉iverilog
要仿真多久结束。和ISE
不同,ISE
的仿真似乎默认1000周期,但是iverilog默认一直仿真。用$stop
替代$finish
相当于断点的效果,在仿真结束后vvp会进入interact模式而非直接退出。
Ctrl
+C
可以停止仿真。
1 | initial begin |
testbench我这里就不写了,毕竟不同人的写法不同,而且单周期的testbench基本上能跑起来就没问题,不需要考虑什么时钟周期乱七八糟的。
3. 用iverilog运行代码
假设mips_tb.v
中的模块为mips_tb
。其中包含了mips
模块
1 | $ iverilog -s mips_tb -o mips_tb.out *.v |
-o
表示将编译结果输出到当前目录下的mips_tb.out
文件中,-s mips_tb
指定仿真的顶层模块名。iverilog默认将没有被实例化的模块设置为root模块,这意味着如果有多个testbench文件的话,iverilog会一起进行仿真。在P7中我们可能会利用不同的testbench进行不同的中断测试,当我们想要使用特定的testbench进行仿真的时候就会需要使用到-s
参数。只有1个testbench的时候可以不加-s
参数。
4. 重定向输出
vvp
进行仿真之后会将CPU
和iverilog
的信息一同输出到标准输出中,我们将这些输出重定向到文件tmp.txt
中。这个文件中不仅包含了CPU
的输出,也包含了iverilog
的仿真信息。我们先将其输出到一个临时文件中。
1 | $ vvp mips_tb.out > my_tmp.txt |
5. 检查输出格式
22级计算机组成对CPU输出格式有要求,在测评的时候也会忽略掉不符合输出格式的输出。
寄存器信息:<仿真时间>@<程序计数器地址>:
数据存储器信息:<仿真时间>@<程序计数器地址>: *<数据存储器地址> <= <写入数据>,如 1746@00003704: *00000018 <= 69b5cca3
但是在正确性的比对中,我们不需要关心时钟周期,只需要关注@
开始的部分即可。
linux
中的grep
指令可以方便地按照正则表达式对文本进行匹配查找。
CPU输出格式的正则表达式可以写为'(@[0-9a-f]{8}: *\*[0-9a-f]{8} *<= *[0-9a-f]{8} *\n)|(@[0-9a-f]{8}: *\$[0-9]{2} *<= *[0-9a-f]{8} *\n)'
但是为了简单起见,我们用@
进行匹配就行。运行:
1 | $ grep '@' my_tmp.txt > my.txt |
这样子我们就把所有含有@
的行选出来输出到后面的文件中了。
比对输出文件
linux
中的diff
指令可以清晰地看到两个文件的差异,缺点是看到的太详细了。不过我个人不太计较。
1 | $ diff -y (-H) -B -b my.txt mars.txt > result.txt |
其中-y
表示将文件“肩并肩”地输出。-H
用于大规模文本比对,我们的规模比较小,不需要。-B
表示不对空行进行比对。-b
表示不对空格进行比对。我们将比较的结果重定向到了result.txt
文件中。
总结
大概要用到这些指令:
1 | $ java -jar mars.jar mc CompactLargeText coL1 test.asm > mars_tmp.txt |
编写成shell脚本
shell脚本在linux中能够方便的运行多条linux指令。在第二学年的春季学期我们也会接触到它的具体写法,因此我也不会。
不过我们也不需要会。
打开ChatGPT
,耐(man)心(man)指(tiao)导(jiao)它帮我们写一个小shell脚本。
1 | !/bin/bash |
将之前提到的所有文件都放在同一个文件目录下。
调用指令
1 | $ touch test.sh |
这会新建一个叫test.sh
的文件,然后将这个文件标记为可执行文件。
然后打开test.sh文件,将上述代码写进去。
我们运行一下:
1 | $ ./test.sh |
成功。
即便不懂shell脚本,瞪几眼也大概能看懂,可读性还是很高的。可以在这个基础上修改一下,让自动化测试符合自己的预期要求。
P5测试
(待补充 ~)
(概率不补充,因为自己也只会胡说八道)。
- 标题: 「BUAA CO」计组小白的自动化测试
- 作者: Squirrel7ang
- 创建于 : 2024-01-09 21:40:00
- 更新于 : 2024-01-15 00:09:01
- 链接: https://redefine.ohevan.com/2024/01/09/CO/AutoTest/
- 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。