#risc-v #simulator #emulator #testing

app lib-rv32-cli

lib_rv32的扩展,提供MCU实现

1个不稳定版本

0.2.0 2021年8月25日

#21 in #riscv

MIT 许可证

53KB
1.5K SLoC

lib-rv32

build tests

概述

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


ISA模拟器

此库可以在实现所需原语在特质的任何内存和寄存器文件上执行指令:lib_rv32_common::traits::{Memory, RegisterFile}。这是为了鼓励使用您所需的任何前端。

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

MCU

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

汇编器

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

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

CLI

模拟器

模拟器的首要用途是跟踪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还通过命令行公开汇编器。您可以使用

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


测试

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

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

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

在测试期间,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

依赖关系

~1.9–3MB
~53K SLoC