#risc-v #汇编 # #指令 #基准 #CPU #verilator

bin+lib rubbler

分割器是一个用 Rust 编写的 RISC-V 汇编器 🦀。这个库的主要目的是将一个简单的 RISC-V 汇编器嵌入到用 verilator 编写的 RISC-V CPU 测试代码中。

2 个版本

0.1.2 2024 年 3 月 5 日
0.1.1 2024 年 3 月 5 日
0.1.0 2024 年 3 月 5 日

#95性能分析

Download history 4/week @ 2024-06-30 19/week @ 2024-07-07 48/week @ 2024-07-28

每月 67 次下载

MIT/Apache

205KB
5.5K SLoC

分割器

rubbler 是一个用 Rust 编写的 RISC-V 汇编器 🦀。这个库的主要目的是将一个简单的 RISC-V 汇编器嵌入到用 verilator 编写的 RISC-V CPU 测试代码中。

此外,还可以安装一个名为 rubble 的命令行程序。rubble 从标准输入读取行,并将表示汇编代码的 '1' 和 '0' 字符串输出到标准输出。

特性

详细的错误解释

$ rubble
> Input RISC-V assembly line(s): (Press <CTRL-d> once finished)
add t0, t1, 5
> Rubbling...
[Line 1] Generator error: `add` instruction expects the following arguments: [RegDest, RegSrc1, RegSrc2].
$ rubble
> Input RISC-V assembly line(s): (Press <CTRL-d> once finished)
jal t0, hello
> Rubbling...
[Line 1] Generator error: Cannot resolve symbol: `hello`.
$ rubble
> Input RISC-V assembly line(s): (Press <CTRL-d> once finished)
hello
> Rubbling...
[Line 1] Syntax error: Unknown opcode or directive `hello`.

支持标签

$ rubble
> Input RISC-V assembly line(s): (Press <CTRL-d> once finished)
fibonacci:
addi t0, zero, 0 # t0
addi t1, zero, 1 # t1
addi t2, zero, 0 # i
loop:
bge t2, a0, end
add t3, t0, t1 # temp
addi t0, t1, 0
addi t1, t3, 0
addi t2, t2, 1
jal t4, loop
end:
addi a0, t0, 0
> Rubbling...
> Here's your bytes:
10010011000000100000000000000000
00010011000000110001000000000000
10010011000000110000000000000000
01100011110111001010001100000000
00110011100011100110001000000000
10010011000000100000001100000000
00010011000000110000111000000000
10010011100000110001001100000000
11101111111111101101111111111110
00010011100001010000001000000000

支持指令

$ rubble
> Input RISC-V assembly line(s): (Press <CTRL-d> once finished)
.section .data
.byte 1, 2, 3
> Rubbling...
> Here's your bytes:
000000010000001000000011

请参阅支持的指令以获取所有支持的指令。

支持的指令

目前,仅支持 RV32I 的一小部分

  • 寄存器-立即数算术操作
    • ADDI, ANDI, ORI, XORI, SLTI, SLTIU, SLLI, SRLI, LUI, AUIPC
  • 寄存器-寄存器算术操作
    • ADD, AND, OR, XOR, SLT, SLTU, SLL, SRL, SRA, SUB
  • 跳转指令
    • JAL, JALR
  • 分支指令
    • BEQ, BNE, BLT, BLTU, BGE, BGEU
  • 加载操作
    • LW, LH, LHU, LB, LBU
  • 存储操作
    • SW, SH, SB

支持的汇编指令

目前,以下指令可供使用

  • .align
  • .p2align
  • .comm
  • .common
  • .section
  • .equ
  • .byte

请参阅RISC-V 汇编程序员手册以获取每个指令的语法。

从源码构建

要求

Rust (请参阅安装 Rust)

构建说明

git clone https://github.com/fuad1502/rubbler.git
cd rubbler
cargo build --release

这些命令会生成 rubbler 可执行文件、rubbler/target/rubbler.h 头文件和 rubbler 目标目录下的 librubbler.a 静态库。

使用示例

Rust

let source = "lui t2, -3";
let expected_res = vec![0b10110111,0b11110011,0b11111111,0b11111111];
let res = rubbler::rubble(source).unwrap();
assert_eq!(res, expected_res);

有关 Rust 中的更多示例,请参阅 docs.rs/rubbler

C/C++

此示例是从rubbler-verilator-example中摘取的代码片段。

#include "rubbler.h"
...
  auto source = "add t0, t1, t2";
  auto bytes = (uint8_t *)malloc(sizeof(uint8_t) * MAX_SIZE);
  uintptr_t size = MAX_SIZE;
  assert(rubble(source, bytes, &size));
...

有关如何使用每个函数的完整解释,请参阅rubbler::ffi模块,或者简单地查看rubbler.h中每个函数的文档字符串。

与Verilator集成

在以下讨论中,我们假设您已经安装了verilator,并且verilator命令可用。有关如何进行安装的说明,请参阅verilator 文档。以下两个示例均来自rubbler-verilator-example

使用Makefile

假设以下项目目录结构

- project
	- main.cpp
	- top.sv
	- Makefile

以下Makefile将从main.cpptop.sv构建main,这两个文件都可以从main.cpp中使用verilatorrubbler库。

VERILATOR_ROOT := /usr/local/share/verilator
VM_SC := 0
VM_TRACE := 0

VERILATOR_OBJS := verilated.o verilated_threads.o verilated_dpi.o

main:main.o obj_dir/Vtop__ALL.a librubbler.a $(VERILATOR_OBJS)
	$(CXX) $^ -o $@

main.o: main.cpp obj_dir/Vtop.h rubbler.h
	$(CXX) \
	-Iobj_dir \
	-I$(VERILATOR_ROOT)/include \
	-I$(VERILATOR_ROOT)/include/vltstd \
	-c main.cpp -o $@

obj_dir/Vtop__ALL.a obj_dir/Vtop.h: top.sv
	verilator -cc --build -j top.sv

rubbler.h librubbler.a: rubbler
	cd rubbler && cargo build --release
	cp rubbler/target/rubbler.h rubbler/target/release/librubbler.a .

rubbler:
	git clone https://github.com/fuad1502/rubbler.git

include $(VERILATOR_ROOT)/include/verilated.mk

.PHONY:clean
clean:
	rm -rf obj_dir
	rm -rf rubbler
	rm librubbler.a rubbler.h
	rm *.o *.d
	rm main

有关完整示例,请参阅rubbler-verilator-example

使用CMake ExternalProject

假设以下项目目录结构

- project
	- main.cpp
	- top.sv
	- CMakeLists.txt

以下CMakeLists.txt文件将从main.cpptop.sv构建main,这两个文件都可以从main.cpp中使用verilatorrubbler库。

cmake_minimum_required(VERSION 3.14)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

project(rubbler-verilator-example)

find_package(verilator REQUIRED)

include(ExternalProject)
ExternalProject_Add(
	rubbler
	GIT_REPOSITORY https://github.com/fuad1502/rubbler.git
	DOWNLOAD_DIR ${CMAKE_BINARY_DIR}
	SOURCE_DIR ${CMAKE_BINARY_DIR}/rubbler
	BINARY_DIR ${CMAKE_BINARY_DIR}/rubbler
	CONFIGURE_COMMAND ""
	INSTALL_COMMAND ""
	BUILD_COMMAND cargo build --release
)
set(RUBBLER_LIB ${CMAKE_BINARY_DIR}/rubbler/target/release/librubbler.a)

add_executable(main main.cpp)
target_include_directories(main PRIVATE ${CMAKE_BINARY_DIR}/rubbler/target)
target_link_libraries(main PRIVATE ${RUBBLER_LIB})
verilate(main SOURCES top.sv)

有关完整示例,请参阅rubbler-verilator-example

二进制安装

要全局使用rubble二进制文件,请使用以下命令安装

cargo install rubbler

问题

  • 尚不支持在内存寻址表达式中使用符号。

计划功能

  • 报告多个错误而不是在检测到第一个错误时终止。
  • 通过添加列信息来增加错误报告的详细程度,并显示与报告一起的违规行。
  • 支持伪指令。

无运行时依赖

~0–1.4MB
~19K SLoC