#risc-v #assembly #simulator #emulator #testing

lib-rv32-asm

lib_rv32 的扩展,提供汇编器功能

1 个不稳定版本

0.2.0 2021年8月25日

#204模拟器


被用于 lib-rv32-cli

MIT 许可协议

32KB
854

lib-rv32

build tests

概述

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

  • lib-rv32-isa: 用于 ISA 模拟的库
  • lib-rv32-mcu: 与 lib_rv32_isa 一起使用的 MCU 的参考实现
  • lib-rv32-asm: 用于汇编 RISC-V 程序的库
  • lib-rv32-cli: 揭示库的 CLI 工具
  • [lib-rv32-wasm]: 使用库的 WASM 绑定的 webapp。

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

汇编器

命令行界面还通过命令行公开了汇编器。您可以使用以下命令将文件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