From 0a7d7616ab1ce07cda1b6fb019dfd8a996189e01 Mon Sep 17 00:00:00 2001 From: liangkangnan Date: Wed, 27 May 2020 23:24:33 +0800 Subject: [PATCH] add new inst test Signed-off-by: liangkangnan --- README.md | 38 ++++++++++++++++++++++++++++++++++++-- pic/new_test_output.png | Bin 0 -> 12745 bytes 2 files changed, 36 insertions(+), 2 deletions(-) create mode 100644 pic/new_test_output.png diff --git a/README.md b/README.md index 675eb55..ac739f9 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ # 2.介绍 -本项目实现的是一个单核32位的小型RISC-V处理器核(tinyriscv),采用verilog语言编写。tinyriscv有以下特点: +本项目实现的是一个单核32位的小型RISC-V处理器核(tinyriscv),采用verilog语言编写。设计目标是对标ARM Cortex-M3系列处理器。tinyriscv有以下特点: 1. 支持RV32IM指令集,通过RISC-V指令兼容性测试; 3. 采用三级流水线,即取指,译码,执行; @@ -34,6 +34,8 @@ **pic**:存放图片; +**tb**:testbench文件; + **FPGA**:存放FPGA相关文件,如约束文件; tinyriscv的整体框架如下: @@ -78,9 +80,17 @@ tinyriscv目前外挂了6个外设,每个外设的空间大小为256MB,地 可以通过百度网盘下载(链接: https://pan.baidu.com/s/1nFaUIwv171PDXuF7TziDFg 提取码: 9ntc),或者通过微云下载[https://share.weiyun.com/59xtmWR](https://share.weiyun.com/59xtmWR),下载完成后直接解压,然后将make所在的路径添加到环境变量里。 +4. 安装python3 + +到python官网下载安装win版本的python,注意要下载python3版本的。网速慢的同学可以通过百度网盘下载(链接: https://pan.baidu.com/s/1gNC8L5dZTsN6E5TJD2rmnQ 提取码: 3b4t),或者通过微云下载[https://share.weiyun.com/XwzSQHND](https://share.weiyun.com/XwzSQHND)。安装完后将python添加到环境变量里。 + ## 4.2运行指令测试程序 -下面以add指令为例,说明如何运行指令测试程序。 +### 4.2.1 运行旧的指令测试程序 + +旧的指令测试程序属于比较早的指令兼容性测试方法,虽然目前RISC-V官方已经不更新了,但仍然是一个比较好的测试参考。 + +下面以add指令为例,说明如何运行旧的指令测试程序。 打开CMD窗口,进入到sim目录,执行以下命令: @@ -90,6 +100,28 @@ tinyriscv目前外挂了6个外设,每个外设的空间大小为256MB,地 ![](./pic/test_output.png) +也可以一次性对所有指令进行测试,方法如下。 + +打开CMD窗口进入到sim目录下,执行以下命令: + +`python .\test_all_isa.py` + +### 4.2.2运行新的指令测试程序 + +新的指令兼容性([riscv-compliance](https://github.com/riscv/riscv-compliance))测试项相对于旧的指令兼容性测试项来说对指令的测试更加严谨,可以精确到每一条指令的运行结果,而且RISC-V官方一直在更新。 + +下面以add指令为例,说明如何运行新的指令测试程序。 + +打开CMD窗口,进入到sim/compliance_test目录,执行以下命令: + +`python compliance_test.py ..\..\tests\riscv-compliance\build_generated\rv32i\I-ADD-01.elf.bin inst.data` + +如果运行成功的话就可以看到"PASS"的打印。其他指令使用方法类似。 + +![new_test_output](./pic/new_test_output.png) + +目前只测试了几条指令,还没全部指令测试过一遍。如有遇到测试失败的指令,可先自行通过查看波形定位问题所在。 + ## 4.3运行C语言程序 C语言程序例程位于tests\example目录里。 @@ -122,6 +154,8 @@ C语言程序例程位于tests\example目录里。 # 7.更新记录 +2020-05-27:增加新的指令兼容性(riscv-compliance)测试项。 + 2020-05-05:支持spi master,增加spi测试例程。 2020-04-25:支持FreeRTOS(v10.3.1)。 diff --git a/pic/new_test_output.png b/pic/new_test_output.png new file mode 100644 index 0000000000000000000000000000000000000000..b041c611f51b2b43bdfe5c8f6dced7c7266e23e4 GIT binary patch literal 12745 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

qe%@r`APUHB~l1F>>%N8r&OD?B)-35>iwQx zWI(I7Knt{usm^&+_rUex4+`rEO$G1j=|r2jJP*Gf2G&kz4k1)>_$yUG{aI0M8@{^l zErH%&JJSKSS32TiTp`GAGSV=RF_;3hO48H~)Cr2<6ytzz0|znohXu`LJ2zq)rY zkZgCt{B3fPF%4iM8%VL+aM4dws_koox``A21DhIo^558$SzPbll7NNr-e8@hXKzeJ z^i{GDD`N6`d5Q>qQk|q_j~3o0?Ji!}fDG`c zv7j(0C*Lix{}rEN=vi})USvaC%|3d5aj=kX6t1Qu(H-w7#_0Im99i+3*T4*@Qqo9elA=aIEwDZouVg)U7no?4_-Ics+MF3<=z6&;iN=h;dH)>aHpe?$XD3 z2AQ1yT`_z%p~EH{yKzm2)KkAJjb}U0{-cVhq7(mNKj=@r%BAkkP)&Xp6`!XjNLe