#risc-v #simulator #testing #emulator #cli-tool

lib-rv32-isa

用于模拟、测试和学习 RISC-V 的库和 CLI 工具

2 个不稳定版本

0.2.0 2021 年 8 月 25 日
0.1.1 2021 年 8 月 25 日

#381模拟


3 个 crates 中使用 (2 个直接使用)

MIT 许可证

35KB
748

lib-rv32

build tests

概述

lib-rv32 是一个 Rust 库集合,用于模拟、学习和汇编 32 位 RISC-V 整数 ISAs。


ISA 模拟器

此库可以针对实现所需原语的任何内存和寄存器文件执行指令,这些原语在 traits lib_rv32_common::traits::{Memory, RegisterFile} 中。这是为了鼓励与您希望的任何前端一起使用。

然而,在 lib_rv32_mcu::* 中提供了参考实现。该库提供从内存、寄存器中读取和执行单个指令的函数。由于用户决定何时调用这些函数,因此这些函数可能适用于大多数用例。

MCU

MCU crate 为与 ISA 模拟器一起使用提供了 MemoryRegisterFile 的实现。有了这个,就可以完全模拟嵌入式 RISC-V 内核。

汇编器

此 crate 可用于汇编简单的 RISC-V 汇编程序。此库提供的主要功能包括

  • assemble_ir: 将指令 &str 汇编到 u32
  • assemble_program: 将程序 &str 汇编到 Vec<u32>
  • assemble_program_buf: 将 BufRead 汇编到 Vec<u32>

命令行界面

仿真器

仿真器的主要用于跟踪 RISC-V 程序的执行并对其行为做出断言。目前它仅支持简单的二进制内存映像(不支持 ELF 二进制文件)。

将断言输入到 JSON 文件中(注意:所有数字都是字符串,以便支持十六进制或十进制基数)。

断言.json:

{
    "registers": {
        "x0": "0x0",
        "a0": "20"
    },
    "memory": {
        "0x0000": "0x00010117"
    }
}

然后运行

lrv-cli -v ./prog.bin -s 24 -a assert.json

这将执行 prog.bin,在 PC 值 0x24 处停止,然后使用 assert.json 中的断言。

程序将逐条指令跟踪执行

[0000]  00010117  |  auipc  sp, 0x10           |  sp <- 0x10000 (65536);
[0004]  fe010113  |  addi   sp, sp, -32        |  sp <- 0xffe0 (65504);
[0008]  00400513  |  addi   a0, zero, 4        |  a0 <- 0x4 (4);
[000c]  00500593  |  addi   a1, zero, 5        |  a1 <- 0x5 (5);
[0010]  00000097  |  auipc  ra, 0x0            |  ra <- 0x10 (16);
[0014]  018080e7  |  jalr   ra, (24)ra         |  ra <- 0x18 (24); pc <- 0x28;
...

完成后,将总结结果

...
[001c]  f0028293  |  addi   t0, t0, -256       |  t0 <- 0xf00 (3840);
[0020]  00a2a023  |  sw     a0, 0(t0)          |  (word *)0x00000f00 <- 0x14 (20);

Reached stop-PC.

a0 == 20
*0x00000000 == 65815

汇编器

CLI 还通过命令行提供了汇编器。您可以使用以下命令将文件 program.s 汇编成 program.bin

lrv-cli-cv program.s-o program.bin


测试

该项目具有非常灵活的测试系统。

在适当的地方提供了单元测试。

此外,为了测试整个系统,可以将测试程序添加到 mcu/tests/programs。一个测试只是一个包含 .c.s 源文件以及一个 test_case.json(包含程序完成后 MCU 状态的断言)的目录。

在测试期间,Cargo 将为每个测试执行以下操作:

  1. 为 RISC-V 编译它
  2. 启动一个新的 MCU
  3. 使用生成的二进制文件对其进行编程
  4. 运行测试程序一定次数的周期
  5. 进行断言
  6. 报告成功或失败

如果测试失败,它将描述导致崩溃的错误或失败的断言,并打印编译测试二进制文件的对象转储。

...
[001c]  f0028293  |  addi   t0, t0, -256       |  t0 <- 0xf00 (3840);
[0020]  00a2a023  |  sw     a0, 0(t0)          |  (word *)0x00000f00 <- 0x14 (20);
Stopping because the stop PC 0x24 was reached.


Failed test: tests/programs/mul@0x00000024: Register assertion failed: (x10=0x00000014) != 0x00000018.

prog.elf:     file format elf32-littleriscv


Disassembly of section .text.init:

00000000 <start>:
   0:   00010117                auipc   sp,0x10
   4:   fe010113                addi    sp,sp,-32 # ffe0 <__global_pointer$+0xf75c>
   8:   00400513                li      a0,4
   c:   00500593                li      a1,5
...

测试在 CI 中运行,但您可以在本地运行,前提是您的系统具有 riscv(32|64)-unknown-elf-gcc

依赖关系

~87KB