| Crates.io | rubbler |
| lib.rs | rubbler |
| version | 0.1.2 |
| created_at | 2024-03-05 08:32:48.818208+00 |
| updated_at | 2024-03-05 10:06:19.169053+00 |
| description | Rubbler is a RISC-V assembler written in Rust 🦀. This library was written with the main purpose of embedding a simple RISC-V assembler inside of a RISC-V CPU test bench code written with verilator. |
| homepage | |
| repository | https://github.com/fuad1502/rubbler |
| max_upload_size | |
| id | 1162825 |
| size | 215,402 |
rubbler is a RISC-V assembler written in Rust 🦀. This library was written with the main purpose of embedding a simple RISC-V assembler inside of a RISC-V CPU test bench code written with verilator.
In addition, a command line program called rubble can also be installed. rubble reads lines from standard input and outputs a string of '1's and '0's representing the assembled code to standard output.
$ 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
See Supported directives for all supported directives.
Right now, only a subset of RV32I are supported:
Right now, only the following directives are available for use:
See RISC-V Assembly Programmer's Manual for the syntax of each directives.
Rust (see installing Rust)
git clone https://github.com/fuad1502/rubbler.git
cd rubbler
cargo build --release
These commands outputs rubbler/target/release/rubble binary, rubbler/target/rubbler.h header and rubbler/target/release/librubbler.a static library.
let source = "lui t2, -3";
let expected_res = vec![0b10110111,0b11110011,0b11111111,0b11111111];
let res = rubbler::rubble(source).unwrap();
assert_eq!(res, expected_res);
For more examples in Rust, see docs.rs/rubbler.
This example is a snippet taken from 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));
...
See docs.rs/rubbler rubbler::ffi module for a complete explanation on how to use each function, or simply look at the documentation string of each function in rubbler.h.
In the following discussion, we assume you have installed verilator, and the verilator command is available. See the verilator doccumentation for instructions on doing so. Both of the following example is taken from rubbler-verilator-example.
Assuming the following project directory structure:
- project
- main.cpp
- top.sv
- Makefile
The following Makefile will build main from main.cpp and top.sv that can use both verilator and rubbler library from main.cpp.
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
See rubbler-verilator-example. for the complete example.
ExternalProjectAssuming the following project directory structure:
- project
- main.cpp
- top.sv
- CMakeLists.txt
The following CMakeLists.txt file will build main from main.cpp and top.sv that can use both verilator and rubbler library from main.cpp.
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)
See rubbler-verilator-example. for the complete example.
To use the rubble binary system wide, install it with the following command:
cargo install rubbler