---
tags: Computer Architecture 2022
---
# Final Project: Analyze femtorv-quark and ensure RV32I compatibility
contributed by 鄭至崴
## Goal
:::warning
以下為期末專題的預期產出
1. 分析 FemtoRV 的實作,善用 Verilator 或 FPGA 來驗證
2. 確保 FemtoRV 可通過 riscv-arch-test:
https://github.com/riscv-non-isa/riscv-arch-test 注意: 你可能要用 V2 分支
3. 探討 FemtoRV 縮減 LUT 的手段,並分析 CSR 的支援
4. 若上述 (2) 無法全部通過 RV32I 測試,改善並提交 pull request
:::
## Prerequisites
### RISC-V toolchains.
In `FIRMWARE/makefile.inc` will automatically install RISC-V toolchains. The default toolchains are provided by SiFive, but the gcc version 8.3.0 is too old. So here I chose [xPack GNU RISC-V Embedded GCC v12.2.0-1](https://xpack.github.io/blog/2022/08/30/riscv-none-elf-gcc-v12-2-0-1-released/).
```diff
else
$(info Configuring for Linux x86_64)
- TOOLCHAIN_WEB=https://static.dev.sifive.com/dev-tools
- TOOLCHAIN_DL_SUFFIX=-x86_64-linux-ubuntu14
- TOOLCHAIN_VER=riscv64-unknown-elf-gcc-8.3.0-2020.04.0
- TOOLCHAIN_GCC_VER=8.3.0
- RVTOOLCHAIN_BIN_PREFIX=riscv64-unknown-elf
+ TOOLCHAIN_WEB=https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack/releases/download/v12.2.0-1/
+ TOOLCHAIN_DL_SUFFIX=-linux-x64
+ TOOLCHAIN_VER=xpack-riscv-none-elf-gcc-12.2.0-1
+ TOOLCHAIN_GCC_VER=12.2.0
+ RVTOOLCHAIN_BIN_PREFIX=riscv-none-elf
endif
endif
```
### Verilator
```
cd $HOME
git clone https://github.com/verilator/verilator
cd verilator
git checkout stable
export VERILATOR_ROOT=`pwd`
./configure
make
```
Modify environment variables.
```
export PATH=$VERILATOR_ROOT/bin:$PATH
```
### iverilog
```
sudo apt-get install iverilog
```
### OpenGL library
```
sudo apt-get install libglfw3 libglfw3-dev
```
## RTL verification
### Configuration
First, we can select our processor by uncommenting the lines in `/FemtoRV/RTL/CONFIGS/bench_config.v`. I am going to ensure RV32I compatibilty so I choose `FEMTORV32_QUARK`.
```bash=
`define NRV_FEMTORV32_QUARK // RV32I (the most elementary femtorv)
//`define NRV_FEMTORV32_ELECTRON // RV32IM
//`define NRV_FEMTORV32_INTERMISSUM // RV32IMzCSR
//`define NRV_FEMTORV32_GRACILIS // RV32IMCzCSR
//`define NRV_FEMTORV32_PETITBATEAU // WIP RF32F !!
//`define NRV_FEMTORV32_TESTDRIVE
```
Second, let's take a look at `FemtoRV/Makefile`
```bash=
include BOARDS/bench.mk
include BOARDS/icestick.mk
include BOARDS/icestick_mecrisp_quintus.mk
include BOARDS/icebreaker.mk
include BOARDS/icefeather.mk
include BOARDS/icesugar.mk
include BOARDS/icesugar_nano.mk
include BOARDS/fomu.mk
include BOARDS/ulx3s.mk
include BOARDS/ecp5_evn.mk
#include BOARDS/arty35_symbiflow.mk
include BOARDS/arty35_yosys_nextpnr.mk
```
It includes the testbench board `BOARDS/bench.mk` we're going to use. We can run the command `make BNECH.firmware_config` to install the RISC-V toolchains automatically, but before that, let's take a look at `/FemtoRV/BOARDS/bench.mk` below.
```bash=
################################################################################
# testbench pseudo-board
################################################################################
BENCH: BENCH.verilator
BENCH.firmware_config:
BOARD=testbench TOOLS/make_config.sh -DBENCH_VERILATOR
(cd FIRMWARE; make libs)
...
```
`BOARD` is an environment variable which is `testbench` now.
`TOOLS/make_config.sh` is at follow.
:::spoiler TOOLS/make_config.sh
```bash=
# Extracts compilation flags from selected board, and
# write them to FIRMWARE/config.mk
cd RTL
iverilog -I PROCESSOR $1 -o tmp.vvp get_config.v
vvp tmp.vvp > ../FIRMWARE/config.mk
rm -f tmp.vvp
echo BOARD=$BOARD >> ../FIRMWARE/config.mk
cat ../FIRMWARE/config.mk
```
:::
It extracts compilation flags from selected board (testbench), and write them to `FIRMWARE/config.mk`.
And last `cd FIRMWARE; make libs`. It compiles graphic library, hardware support lib, lib with printf(), and C runtime for baremetal.
:::spoiler FIRMWARE/Makefile
```bash=
libs:
(cd LIBFEMTOGL; make clean all) # Compile graphic library
(cd LIBFEMTORV32; make clean all) # Compile hardware support lib
(cd LIBFEMTOC; make clean all) # Compile lib with printf() replacement function
(cd CRT; make clean all) # Compile C runtime for baremetal
@echo ==== Generated femtorv32 libs.
```
:::
Now we can run the command to install RISC-V toolchain.
```
make BENCH.firmware_config
```
:::spoiler Result
```bash=
Configuring for Linux x86_64
Makefile:30: warning: overriding recipe for target 'clean'
FIRMWARE/makefile.inc:170: warning: ignoring old recipe for target 'clean'
FIRMWARE/makefile.inc:98: warning: ignoring prerequisites on suffix rule definition
FIRMWARE/makefile.inc:102: warning: ignoring prerequisites on suffix rule definition
FIRMWARE/makefile.inc:106: warning: ignoring prerequisites on suffix rule definition
BOARD=testbench TOOLS/make_config.sh -DBENCH_VERILATOR
./PROCESSOR/femtorv32_quark.v:68: warning: Attributes are not supported on net declaration assignments and will be discarded.
ARCH=rv32i
OPTIMIZE=-Os
ABI=ilp32
RAM_SIZE= 65536
DEVICES= -DSSD1351=1
BOARD=testbench
(cd FIRMWARE; make libs)
make[1]: Entering directory '/home/cheng/learn-fpga/FemtoRV/FIRMWARE'
(cd LIBFEMTOGL; make clean all) # Compile graphic library
make[2]: Entering directory '/home/cheng/learn-fpga/FemtoRV/FIRMWARE/LIBFEMTOGL'
Configuring for Linux x86_64
../makefile.inc:98: warning: ignoring prerequisites on suffix rule definition
../makefile.inc:102: warning: ignoring prerequisites on suffix rule definition
../makefile.inc:106: warning: ignoring prerequisites on suffix rule definition
rm -f *.o *.elf *.hex *.exe *~ *.a *.bin *.list
/home/cheng/learn-fpga/FemtoRV/FIRMWARE//TOOLCHAIN/xpack-riscv-none-elf-gcc-12.2.0-1-linux-x64/bin/riscv-none-elf-as -march=rv32i -mabi=ilp32 -defsym SSD1351=1 -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTOGL -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTORV32 -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTOC font_8x16.S -o font_8x16.o
/home/cheng/learn-fpga/FemtoRV/FIRMWARE//TOOLCHAIN/xpack-riscv-none-elf-gcc-12.2.0-1-linux-x64/bin/riscv-none-elf-as -march=rv32i -mabi=ilp32 -defsym SSD1351=1 -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTOGL -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTORV32 -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTOC font_8x8.S -o font_8x8.o
/home/cheng/learn-fpga/FemtoRV/FIRMWARE//TOOLCHAIN/xpack-riscv-none-elf-gcc-12.2.0-1-linux-x64/bin/riscv-none-elf-as -march=rv32i -mabi=ilp32 -defsym SSD1351=1 -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTOGL -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTORV32 -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTOC font_5x6.S -o font_5x6.o
/home/cheng/learn-fpga/FemtoRV/FIRMWARE//TOOLCHAIN/xpack-riscv-none-elf-gcc-12.2.0-1-linux-x64/bin/riscv-none-elf-as -march=rv32i -mabi=ilp32 -defsym SSD1351=1 -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTOGL -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTORV32 -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTOC font_3x5.S -o font_3x5.o
/home/cheng/learn-fpga/FemtoRV/FIRMWARE//TOOLCHAIN/xpack-riscv-none-elf-gcc-12.2.0-1-linux-x64/bin/riscv-none-elf-gcc -Os -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTOGL -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTORV32 -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTOC -DSSD1351=1 -fno-pic -march=rv32i -mabi=ilp32 -fno-stack-protector -w -Wl,--no-relax -c femtoGL.c
/home/cheng/learn-fpga/FemtoRV/FIRMWARE//TOOLCHAIN/xpack-riscv-none-elf-gcc-12.2.0-1-linux-x64/bin/riscv-none-elf-gcc -Os -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTOGL -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTORV32 -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTOC -DSSD1351=1 -fno-pic -march=rv32i -mabi=ilp32 -fno-stack-protector -w -Wl,--no-relax -c femtoGLtext.c
/home/cheng/learn-fpga/FemtoRV/FIRMWARE//TOOLCHAIN/xpack-riscv-none-elf-gcc-12.2.0-1-linux-x64/bin/riscv-none-elf-gcc -Os -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTOGL -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTORV32 -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTOC -DSSD1351=1 -fno-pic -march=rv32i -mabi=ilp32 -fno-stack-protector -w -Wl,--no-relax -c femtoGLfill_rect.c
/home/cheng/learn-fpga/FemtoRV/FIRMWARE//TOOLCHAIN/xpack-riscv-none-elf-gcc-12.2.0-1-linux-x64/bin/riscv-none-elf-gcc -Os -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTOGL -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTORV32 -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTOC -DSSD1351=1 -fno-pic -march=rv32i -mabi=ilp32 -fno-stack-protector -w -Wl,--no-relax -c femtoGLsetpixel.c
/home/cheng/learn-fpga/FemtoRV/FIRMWARE//TOOLCHAIN/xpack-riscv-none-elf-gcc-12.2.0-1-linux-x64/bin/riscv-none-elf-gcc -Os -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTOGL -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTORV32 -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTOC -DSSD1351=1 -fno-pic -march=rv32i -mabi=ilp32 -fno-stack-protector -w -Wl,--no-relax -c femtoGLline.c
/home/cheng/learn-fpga/FemtoRV/FIRMWARE//TOOLCHAIN/xpack-riscv-none-elf-gcc-12.2.0-1-linux-x64/bin/riscv-none-elf-gcc -Os -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTOGL -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTORV32 -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTOC -DSSD1351=1 -fno-pic -march=rv32i -mabi=ilp32 -fno-stack-protector -w -Wl,--no-relax -c femtoGLfill_poly.c
/home/cheng/learn-fpga/FemtoRV/FIRMWARE//TOOLCHAIN/xpack-riscv-none-elf-gcc-12.2.0-1-linux-x64/bin/riscv-none-elf-gcc -Os -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTOGL -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTORV32 -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTOC -DSSD1351=1 -fno-pic -march=rv32i -mabi=ilp32 -fno-stack-protector -w -Wl,--no-relax -c tty_init.c
/home/cheng/learn-fpga/FemtoRV/FIRMWARE//TOOLCHAIN/xpack-riscv-none-elf-gcc-12.2.0-1-linux-x64/bin/riscv-none-elf-gcc -Os -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTOGL -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTORV32 -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTOC -DSSD1351=1 -fno-pic -march=rv32i -mabi=ilp32 -fno-stack-protector -w -Wl,--no-relax -c max7219_text.c
/home/cheng/learn-fpga/FemtoRV/FIRMWARE//TOOLCHAIN/xpack-riscv-none-elf-gcc-12.2.0-1-linux-x64/bin/riscv-none-elf-gcc -Os -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTOGL -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTORV32 -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTOC -DSSD1351=1 -fno-pic -march=rv32i -mabi=ilp32 -fno-stack-protector -w -Wl,--no-relax -c FGA_mode.c
/home/cheng/learn-fpga/FemtoRV/FIRMWARE//TOOLCHAIN/xpack-riscv-none-elf-gcc-12.2.0-1-linux-x64/bin/riscv-none-elf-gcc -Os -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTOGL -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTORV32 -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTOC -DSSD1351=1 -fno-pic -march=rv32i -mabi=ilp32 -fno-stack-protector -w -Wl,--no-relax -c FGA.c
/home/cheng/learn-fpga/FemtoRV/FIRMWARE//TOOLCHAIN/xpack-riscv-none-elf-gcc-12.2.0-1-linux-x64/bin/riscv-none-elf-gcc -Os -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTOGL -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTORV32 -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTOC -DSSD1351=1 -fno-pic -march=rv32i -mabi=ilp32 -fno-stack-protector -w -Wl,--no-relax -c femto_GUI.c
/home/cheng/learn-fpga/FemtoRV/FIRMWARE//TOOLCHAIN/xpack-riscv-none-elf-gcc-12.2.0-1-linux-x64/bin/riscv-none-elf-ar cq libfemtoGL.a font_8x16.o font_8x8.o font_5x6.o font_3x5.o femtoGL.o femtoGLtext.o femtoGLfill_rect.o femtoGLsetpixel.o femtoGLline.o femtoGLfill_poly.o tty_init.o max7219_text.o FGA_mode.o FGA.o femto_GUI.o
/home/cheng/learn-fpga/FemtoRV/FIRMWARE//TOOLCHAIN/xpack-riscv-none-elf-gcc-12.2.0-1-linux-x64/bin/riscv-none-elf-ranlib libfemtoGL.a
make[2]: Leaving directory '/home/cheng/learn-fpga/FemtoRV/FIRMWARE/LIBFEMTOGL'
(cd LIBFEMTORV32; make clean all) # Compile hardware support lib
make[2]: Entering directory '/home/cheng/learn-fpga/FemtoRV/FIRMWARE/LIBFEMTORV32'
Configuring for Linux x86_64
../makefile.inc:98: warning: ignoring prerequisites on suffix rule definition
../makefile.inc:102: warning: ignoring prerequisites on suffix rule definition
../makefile.inc:106: warning: ignoring prerequisites on suffix rule definition
rm -f *.o *.elf *.hex *.exe *~ *.a *.bin *.list
/home/cheng/learn-fpga/FemtoRV/FIRMWARE//TOOLCHAIN/xpack-riscv-none-elf-gcc-12.2.0-1-linux-x64/bin/riscv-none-elf-as -march=rv32i -mabi=ilp32 -defsym SSD1351=1 -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTOGL -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTORV32 -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTOC femtorv32.S -o femtorv32.o
/home/cheng/learn-fpga/FemtoRV/FIRMWARE//TOOLCHAIN/xpack-riscv-none-elf-gcc-12.2.0-1-linux-x64/bin/riscv-none-elf-as -march=rv32i -mabi=ilp32 -defsym SSD1351=1 -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTOGL -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTORV32 -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTOC max7219.S -o max7219.o
/home/cheng/learn-fpga/FemtoRV/FIRMWARE//TOOLCHAIN/xpack-riscv-none-elf-gcc-12.2.0-1-linux-x64/bin/riscv-none-elf-as -march=rv32i -mabi=ilp32 -defsym SSD1351=1 -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTOGL -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTORV32 -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTOC ssd1351_1331.S -o ssd1351_1331.o
/home/cheng/learn-fpga/FemtoRV/FIRMWARE//TOOLCHAIN/xpack-riscv-none-elf-gcc-12.2.0-1-linux-x64/bin/riscv-none-elf-as -march=rv32i -mabi=ilp32 -defsym SSD1351=1 -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTOGL -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTORV32 -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTOC ssd1351_1331_init.S -o ssd1351_1331_init.o
/home/cheng/learn-fpga/FemtoRV/FIRMWARE//TOOLCHAIN/xpack-riscv-none-elf-gcc-12.2.0-1-linux-x64/bin/riscv-none-elf-as -march=rv32i -mabi=ilp32 -defsym SSD1351=1 -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTOGL -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTORV32 -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTOC uart.S -o uart.o
/home/cheng/learn-fpga/FemtoRV/FIRMWARE//TOOLCHAIN/xpack-riscv-none-elf-gcc-12.2.0-1-linux-x64/bin/riscv-none-elf-gcc -Os -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTOGL -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTORV32 -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTOC -DSSD1351=1 -fno-pic -march=rv32i -mabi=ilp32 -fno-stack-protector -w -Wl,--no-relax -c keyboard.c
/home/cheng/learn-fpga/FemtoRV/FIRMWARE//TOOLCHAIN/xpack-riscv-none-elf-gcc-12.2.0-1-linux-x64/bin/riscv-none-elf-gcc -Os -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTOGL -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTORV32 -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTOC -DSSD1351=1 -fno-pic -march=rv32i -mabi=ilp32 -fno-stack-protector -w -Wl,--no-relax -c virtual_io.c
/home/cheng/learn-fpga/FemtoRV/FIRMWARE//TOOLCHAIN/xpack-riscv-none-elf-gcc-12.2.0-1-linux-x64/bin/riscv-none-elf-gcc -Os -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTOGL -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTORV32 -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTOC -DSSD1351=1 -fno-pic -march=rv32i -mabi=ilp32 -fno-stack-protector -w -Wl,--no-relax -c wait_cycles.c
/home/cheng/learn-fpga/FemtoRV/FIRMWARE//TOOLCHAIN/xpack-riscv-none-elf-gcc-12.2.0-1-linux-x64/bin/riscv-none-elf-gcc -Os -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTOGL -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTORV32 -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTOC -DSSD1351=1 -fno-pic -march=rv32i -mabi=ilp32 -fno-stack-protector -w -Wl,--no-relax -c microwait.c
/home/cheng/learn-fpga/FemtoRV/FIRMWARE//TOOLCHAIN/xpack-riscv-none-elf-gcc-12.2.0-1-linux-x64/bin/riscv-none-elf-gcc -Os -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTOGL -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTORV32 -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTOC -DSSD1351=1 -fno-pic -march=rv32i -mabi=ilp32 -fno-stack-protector -w -Wl,--no-relax -c milliwait.c
/home/cheng/learn-fpga/FemtoRV/FIRMWARE//TOOLCHAIN/xpack-riscv-none-elf-gcc-12.2.0-1-linux-x64/bin/riscv-none-elf-gcc -Os -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTOGL -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTORV32 -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTOC -DSSD1351=1 -fno-pic -march=rv32i -mabi=ilp32 -fno-stack-protector -w -Wl,--no-relax -c milliseconds.c
/home/cheng/learn-fpga/FemtoRV/FIRMWARE//TOOLCHAIN/xpack-riscv-none-elf-gcc-12.2.0-1-linux-x64/bin/riscv-none-elf-gcc -Os -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTOGL -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTORV32 -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTOC -DSSD1351=1 -fno-pic -march=rv32i -mabi=ilp32 -fno-stack-protector -w -Wl,--no-relax -c spi_sd.c
/home/cheng/learn-fpga/FemtoRV/FIRMWARE//TOOLCHAIN/xpack-riscv-none-elf-gcc-12.2.0-1-linux-x64/bin/riscv-none-elf-gcc -Os -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTOGL -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTORV32 -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTOC -DSSD1351=1 -fno-pic -march=rv32i -mabi=ilp32 -fno-stack-protector -w -Wl,--no-relax -c cycles_32.c
/home/cheng/learn-fpga/FemtoRV/FIRMWARE//TOOLCHAIN/xpack-riscv-none-elf-gcc-12.2.0-1-linux-x64/bin/riscv-none-elf-as -march=rv32i -mabi=ilp32 -defsym SSD1351=1 -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTOGL -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTORV32 -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTOC cycles_64.S -o cycles_64.o
/home/cheng/learn-fpga/FemtoRV/FIRMWARE//TOOLCHAIN/xpack-riscv-none-elf-gcc-12.2.0-1-linux-x64/bin/riscv-none-elf-gcc -Os -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTOGL -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTORV32 -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTOC -DSSD1351=1 -fno-pic -march=rv32i -mabi=ilp32 -fno-stack-protector -w -Wl,--no-relax -c filesystem.c
/home/cheng/learn-fpga/FemtoRV/FIRMWARE//TOOLCHAIN/xpack-riscv-none-elf-gcc-12.2.0-1-linux-x64/bin/riscv-none-elf-gcc -Os -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTOGL -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTORV32 -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTOC -DSSD1351=1 -fno-pic -march=rv32i -mabi=ilp32 -fno-stack-protector -w -Wl,--no-relax -c exec.c
/home/cheng/learn-fpga/FemtoRV/FIRMWARE//TOOLCHAIN/xpack-riscv-none-elf-gcc-12.2.0-1-linux-x64/bin/riscv-none-elf-gcc -Os -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTOGL -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTORV32 -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTOC -DSSD1351=1 -fno-pic -march=rv32i -mabi=ilp32 -fno-stack-protector -w -Wl,--no-relax -c femto_elf.c
/home/cheng/learn-fpga/FemtoRV/FIRMWARE//TOOLCHAIN/xpack-riscv-none-elf-gcc-12.2.0-1-linux-x64/bin/riscv-none-elf-gcc -Os -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTOGL -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTORV32 -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTOC -DSSD1351=1 -fno-pic -march=rv32i -mabi=ilp32 -fno-stack-protector -w -Wl,--no-relax -c fat_io_lib/fat_access.c
/home/cheng/learn-fpga/FemtoRV/FIRMWARE//TOOLCHAIN/xpack-riscv-none-elf-gcc-12.2.0-1-linux-x64/bin/riscv-none-elf-gcc -Os -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTOGL -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTORV32 -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTOC -DSSD1351=1 -fno-pic -march=rv32i -mabi=ilp32 -fno-stack-protector -w -Wl,--no-relax -c fat_io_lib/fat_cache.c
/home/cheng/learn-fpga/FemtoRV/FIRMWARE//TOOLCHAIN/xpack-riscv-none-elf-gcc-12.2.0-1-linux-x64/bin/riscv-none-elf-gcc -Os -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTOGL -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTORV32 -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTOC -DSSD1351=1 -fno-pic -march=rv32i -mabi=ilp32 -fno-stack-protector -w -Wl,--no-relax -c fat_io_lib/fat_filelib.c
/home/cheng/learn-fpga/FemtoRV/FIRMWARE//TOOLCHAIN/xpack-riscv-none-elf-gcc-12.2.0-1-linux-x64/bin/riscv-none-elf-gcc -Os -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTOGL -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTORV32 -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTOC -DSSD1351=1 -fno-pic -march=rv32i -mabi=ilp32 -fno-stack-protector -w -Wl,--no-relax -c fat_io_lib/fat_format.c
/home/cheng/learn-fpga/FemtoRV/FIRMWARE//TOOLCHAIN/xpack-riscv-none-elf-gcc-12.2.0-1-linux-x64/bin/riscv-none-elf-gcc -Os -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTOGL -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTORV32 -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTOC -DSSD1351=1 -fno-pic -march=rv32i -mabi=ilp32 -fno-stack-protector -w -Wl,--no-relax -c fat_io_lib/fat_misc.c
/home/cheng/learn-fpga/FemtoRV/FIRMWARE//TOOLCHAIN/xpack-riscv-none-elf-gcc-12.2.0-1-linux-x64/bin/riscv-none-elf-gcc -Os -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTOGL -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTORV32 -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTOC -DSSD1351=1 -fno-pic -march=rv32i -mabi=ilp32 -fno-stack-protector -w -Wl,--no-relax -c fat_io_lib/fat_string.c
/home/cheng/learn-fpga/FemtoRV/FIRMWARE//TOOLCHAIN/xpack-riscv-none-elf-gcc-12.2.0-1-linux-x64/bin/riscv-none-elf-gcc -Os -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTOGL -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTORV32 -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTOC -DSSD1351=1 -fno-pic -march=rv32i -mabi=ilp32 -fno-stack-protector -w -Wl,--no-relax -c fat_io_lib/fat_table.c
/home/cheng/learn-fpga/FemtoRV/FIRMWARE//TOOLCHAIN/xpack-riscv-none-elf-gcc-12.2.0-1-linux-x64/bin/riscv-none-elf-gcc -Os -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTOGL -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTORV32 -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTOC -DSSD1351=1 -fno-pic -march=rv32i -mabi=ilp32 -fno-stack-protector -w -Wl,--no-relax -c fat_io_lib/fat_write.c
/home/cheng/learn-fpga/FemtoRV/FIRMWARE//TOOLCHAIN/xpack-riscv-none-elf-gcc-12.2.0-1-linux-x64/bin/riscv-none-elf-ar cq libfemtorv32.a femtorv32.o max7219.o ssd1351_1331.o ssd1351_1331_init.o uart.o keyboard.o virtual_io.o wait_cycles.o microwait.o milliwait.o milliseconds.o spi_sd.o cycles_32.o cycles_64.o filesystem.o exec.o femto_elf.o fat_access.o fat_cache.o fat_filelib.o fat_format.o fat_misc.o fat_string.o fat_table.o fat_write.o
/home/cheng/learn-fpga/FemtoRV/FIRMWARE//TOOLCHAIN/xpack-riscv-none-elf-gcc-12.2.0-1-linux-x64/bin/riscv-none-elf-ranlib libfemtorv32.a
make[2]: Leaving directory '/home/cheng/learn-fpga/FemtoRV/FIRMWARE/LIBFEMTORV32'
(cd LIBFEMTOC; make clean all) # Compile lib with printf() replacement function
make[2]: Entering directory '/home/cheng/learn-fpga/FemtoRV/FIRMWARE/LIBFEMTOC'
Configuring for Linux x86_64
../makefile.inc:98: warning: ignoring prerequisites on suffix rule definition
../makefile.inc:102: warning: ignoring prerequisites on suffix rule definition
../makefile.inc:106: warning: ignoring prerequisites on suffix rule definition
rm -f *.o *.elf *.hex *.exe *~ *.a *.bin *.list
/home/cheng/learn-fpga/FemtoRV/FIRMWARE//TOOLCHAIN/xpack-riscv-none-elf-gcc-12.2.0-1-linux-x64/bin/riscv-none-elf-gcc -Os -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTOGL -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTORV32 -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTOC -DSSD1351=1 -fno-pic -march=rv32i -mabi=ilp32 -fno-stack-protector -w -Wl,--no-relax -c print.c
/home/cheng/learn-fpga/FemtoRV/FIRMWARE//TOOLCHAIN/xpack-riscv-none-elf-gcc-12.2.0-1-linux-x64/bin/riscv-none-elf-gcc -Os -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTOGL -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTORV32 -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTOC -DSSD1351=1 -fno-pic -march=rv32i -mabi=ilp32 -fno-stack-protector -w -Wl,--no-relax -c printf.c
/home/cheng/learn-fpga/FemtoRV/FIRMWARE//TOOLCHAIN/xpack-riscv-none-elf-gcc-12.2.0-1-linux-x64/bin/riscv-none-elf-ar cq libfemtoc.a print.o printf.o
/home/cheng/learn-fpga/FemtoRV/FIRMWARE//TOOLCHAIN/xpack-riscv-none-elf-gcc-12.2.0-1-linux-x64/bin/riscv-none-elf-ranlib libfemtoc.a
make[2]: Leaving directory '/home/cheng/learn-fpga/FemtoRV/FIRMWARE/LIBFEMTOC'
(cd CRT; make clean all) # Compile C runtime for baremetal
make[2]: Entering directory '/home/cheng/learn-fpga/FemtoRV/FIRMWARE/CRT'
Configuring for Linux x86_64
../makefile.inc:98: warning: ignoring prerequisites on suffix rule definition
../makefile.inc:102: warning: ignoring prerequisites on suffix rule definition
../makefile.inc:106: warning: ignoring prerequisites on suffix rule definition
rm -f *.o *.elf *.hex *.exe *~ *.a *.bin *.list
/home/cheng/learn-fpga/FemtoRV/FIRMWARE//TOOLCHAIN/xpack-riscv-none-elf-gcc-12.2.0-1-linux-x64/bin/riscv-none-elf-as -march=rv32i -mabi=ilp32 -defsym SSD1351=1 -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTOGL -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTORV32 -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTOC crt0_baremetal.S -o crt0_baremetal.o
/home/cheng/learn-fpga/FemtoRV/FIRMWARE//TOOLCHAIN/xpack-riscv-none-elf-gcc-12.2.0-1-linux-x64/bin/riscv-none-elf-as -march=rv32i -mabi=ilp32 -defsym SSD1351=1 -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTOGL -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTORV32 -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTOC crt0_spiflash.S -o crt0_spiflash.o
/home/cheng/learn-fpga/FemtoRV/FIRMWARE//TOOLCHAIN/xpack-riscv-none-elf-gcc-12.2.0-1-linux-x64/bin/riscv-none-elf-gcc -Os -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTOGL -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTORV32 -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTOC -DSSD1351=1 -fno-pic -march=rv32i -mabi=ilp32 -fno-stack-protector -w -Wl,--no-relax -c syscalls.c
make[2]: Leaving directory '/home/cheng/learn-fpga/FemtoRV/FIRMWARE/CRT'
==== Generated femtorv32 libs.
make[1]: Leaving directory '/home/cheng/learn-fpga/FemtoRV/FIRMWARE'
```
:::
### Producing a RISC-V baremetal executable
Let's quickly review how an executable object program is made. [image source](https://blog.louie.lu/2016/09/15/csapp-chapter-7-linking-%E7%AD%86%E8%A8%98/)

- Preprocessor produces ASCII intermediate file
- Compiler produces assembly
- Assembler traslate it to relocatable object file
- Linker links other required system object files together and produces executable object file
Now we are going to procude a RISC-V baremetal executable object program, so we have to define our linker action. The following linker script in `FemtoRV/FIRMWARE/CRT/baremetal.ld` is to do so.
```bash=
MEMORY
{
BRAM (RWX) : ORIGIN = 0x0000, LENGTH = 0x10000
}
SECTIONS
{
.text :
{
crt0_baremetal.o (.text)
*(.text)
_end = .; /* as expected by syscalls.c */
}
}
```
The following sentences are reference from [黃瑋盛](https://hackmd.io/@N9qHU_eLRvKyfDfJk8cDXA/Byj08q3jK#RTL-verification). He explains the importance of `crt0_baremetal.S`.
> In the same directory, crt0_baremetal.S will initailize the C runtime that replaces gcc’s default crt0.S. It’s necessary because crt0_baremetal.S will loads the IO base address in the global pointer and initializes the stack pointer at the end of the RAM. The default one won’t initialize the stack pointer because it is the job of the OS need to do.
Let's take a look at `FIRMWARE/makefile.inc` that the part mentions baremetal.elf.
```bash=
# Generate a "bare metal elf", to be loaded from address 0 (rule for conversion to .hex file in makefile.inc)
# The generated ".hex" file is directly included in the Verilog files, for memory initialization
%.baremetal.elf: %.o $(RV_BINARIES)
$(RVLD) $(RVLDFLAGS) -T$(FIRMWARE_DIR)/CRT/baremetal.ld $< -o $@ $(FEMTORV32_LIBS_SMALL) $(RVGCC_LIB)
```
-T is the argument for our linker script.
After running this command, linker will output an executable object file. Next we have to transform elf to hex, because of `readmemh()` function in `/FemtoRV/RTL/femtosoc.v` written in Verilog can only read hex file. We can find the makefile rule under `/FemtoRV/FIRMWARE/makefile.inc`
```bash=
#Rule to convert a .elf executable into a .hex file for verilog 'readmemh()'
# command, using my 'firmware_words' utility to parse the .elf executable.
# It is used for "bare metal" executables, compiled with linker script,
# starting at address 0 (firmware for IceStick, or femtOS commander.c for ULX3S)
# max_addr is set to 64k, because standard elf are meant to be run from 64k offset
# (then on the ULX3S, there is room for both femtOS in the first 64ks and the loaded
# user executable)
%.hex: %.baremetal.elf $(FIRMWARE_DIR)/TOOLS/firmware_words
$(FIRMWARE_DIR)/TOOLS/firmware_words $< -ram $(RAM_SIZE) -max_addr 65535 -out $@
cp $@ $(FIRMWARE_DIR)/firmware.hex
echo $@ > $(FIRMWARE_DIR)/firmware.txt
```
Finally, we can implement a C code on FemtoRV-quark through the following command.
```
make BENCH
```
This command is also in `FemtoRV/BOARDS/bench.mk`
```bash=
################################################################################
# testbench pseudo-board
################################################################################
BENCH: BENCH.verilator
...
BENCH.verilator:
verilator -DBENCH_VERILATOR --top-module femtoRV32_bench \
-IRTL -IRTL/PROCESSOR -IRTL/DEVICES -IRTL/PLL \
-CFLAGS '-I../SIM' -LDFLAGS '-lglfw -lGL' \
-FI FPU_funcs.h \
--cc --exe SIM/sim_main.cpp SIM/FPU_funcs.cpp SIM/SSD1351.cpp RTL/femtosoc_bench.v
(cd obj_dir; make -f VfemtoRV32_bench.mk)
obj_dir/VfemtoRV32_bench
```
### Implement Example
I take `mandelbrot.c` in `/FemtoRV/FIRMWARE/EXAMPLES` for examples. Use the following command to make hex file under `/FemtoRV/FIRMWARE/EXAMPLES`.
```
make mandelbrot.hex
```
:::spoiler Result
```bash=
Configuring for Linux x86_64
../makefile.inc:98: warning: ignoring prerequisites on suffix rule definition
../makefile.inc:102: warning: ignoring prerequisites on suffix rule definition
../makefile.inc:106: warning: ignoring prerequisites on suffix rule definition
/home/cheng/learn-fpga/FemtoRV/FIRMWARE//TOOLCHAIN/xpack-riscv-none-elf-gcc-12.2.0-1-linux-x64/bin/riscv-none-elf-gcc -Os -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTOGL -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTORV32 -I/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTOC -DSSD1351=1 -fno-pic -march=rv32i -mabi=ilp32 -fno-stack-protector -w -Wl,--no-relax -c mandelbrot.c
/home/cheng/learn-fpga/FemtoRV/FIRMWARE//TOOLCHAIN/xpack-riscv-none-elf-gcc-12.2.0-1-linux-x64/bin/riscv-none-elf-ld -m elf32lriscv -b elf32-littleriscv --no-relax -T/home/cheng/learn-fpga/FemtoRV/FIRMWARE//CRT/baremetal.ld mandelbrot.o -o mandelbrot.baremetal.elf -L/home/cheng/learn-fpga/FemtoRV/FIRMWARE//TOOLCHAIN/xpack-riscv-none-elf-gcc-12.2.0-1-linux-x64/riscv-none-elf/lib/rv32i/ilp32 -L/home/cheng/learn-fpga/FemtoRV/FIRMWARE//CRT -L/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTOGL -L/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTORV32 -L/home/cheng/learn-fpga/FemtoRV/FIRMWARE//LIBFEMTOC -lfemtoGL -lfemtorv32 -lfemtoc /home/cheng/learn-fpga/FemtoRV/FIRMWARE//TOOLCHAIN/xpack-riscv-none-elf-gcc-12.2.0-1-linux-x64/riscv-none-elf/lib/rv32i/ilp32/libc.a /home/cheng/learn-fpga/FemtoRV/FIRMWARE//TOOLCHAIN/xpack-riscv-none-elf-gcc-12.2.0-1-linux-x64/riscv-none-elf/lib/rv32i/ilp32/libm.a /home/cheng/learn-fpga/FemtoRV/FIRMWARE//TOOLCHAIN/xpack-riscv-none-elf-gcc-12.2.0-1-linux-x64/lib/gcc/riscv-none-elf/12.2.0/rv32i/ilp32/libgcc.a
/home/cheng/learn-fpga/FemtoRV/FIRMWARE//TOOLS/firmware_words mandelbrot.baremetal.elf -ram 65536 -max_addr 65535 -out mandelbrot.hex
RAM SIZE=65536
LOAD ELF: mandelbrot.baremetal.elf
max address=2248
Code size: 562 words ( total RAM size: 16384 words )
Occupancy: 3%
testing MAX_ADDR limit: 65535
max_addr OK
SAVE HEX: mandelbrot.hex
cp mandelbrot.hex /home/cheng/learn-fpga/FemtoRV/FIRMWARE//firmware.hex
echo mandelbrot.hex > /home/cheng/learn-fpga/FemtoRV/FIRMWARE//firmware.txt
rm mandelbrot.baremetal.elf mandelbrot.o
```
:::
Next, we can run this code by FemtoRV-quark through this command comes by follow under `/FemtoRV`.
```
make BENCH
```
The result of testbench are shown below.

## FemtoRV on riscv-arch-test
### What is riscv-arch-test?
Let me first instroduce [riscv-arch-test](https://github.com/riscv-non-isa/riscv-arch-test/tree/old-framework-2.x).
I am working on older branch `old-framework-2.x` though it is already unsupported. `Riscv-arch-test` provides the fundamental set of test to ensure our RISC-V model can run basic instructions correctly. Taking RV32I riscv-arch-test as an example, it will do `ADD`, `ADDI`, `XOR`, etc.
### How does it work?
We have to setup our test target. There's an example in `riscv-arch-test/riscv-target/example-target/`. Three main items we have to create are described below.
1. linker script : defines the entry point and sections on memory locations.
2. model_test.h : header file provding target specific assembly macro definitions.
3. device : a directory defines how testing code should be compile and run. Two main variables are `COMPILE_TARGET` and `RUN_TARGET`.
If the setting above are all set, then modify makefiles to run the test. To notice that we need to generate a `test signature`. Here is the explanation in [README](https://github.com/riscv-non-isa/riscv-arch-test/tree/old-framework-2.x/doc).
>Each test in the architectural test pool generates a `test signature`, which represents the data written into specific memory locations during the execution of the test. The signature typically will record values (or sanitised values) of the operations carried out in the test. More details on the format and nature of the signatures is available in the Test Format Specification
The `test signature` will be compare with `reference signature`. Explanation is as follow.
>In order to claim that a device/implementation has passed the RISC-V Architecture Tests, the `test signatures` obtained from the execution of the tests on the implementation need to be compared against a set of golden `reference signature`. These reference signatures are currently generated by the RISC-V SAIL formal model and statically hosted in the repository for each test.
The concept is very similar to [LeetCode](https://leetcode.com/problemset/all/). They both compare the answer to the reference, but `riscv-arch-test` focus on the data written in specific memory locations during execution time.
Here is a part of the Makefile in `riscv-arch-test`.
```bash=
export SUITEDIR = $(ROOTDIR)/riscv-test-suite/rv$(XLEN)i_m/$(RISCV_DEVICE)
compile:
$(MAKE) $(JOBS) \
RISCV_TARGET=$(RISCV_TARGET) \
RISCV_DEVICE=$(RISCV_DEVICE) \
compile -C $(SUITEDIR)
simulate:
$(MAKE) $(JOBS) \
RISCV_TARGET=$(RISCV_TARGET) \
RISCV_DEVICE=$(RISCV_DEVICE) \
run -C $(SUITEDIR)
verify: simulate
riscv-test-env/verify.sh
```
Let's look through how does the target `compile` is made. It runs the makefile target `compile` in `SUITEDIR` directory. Makefile in `SUITEDIR` show as follow.
```bash=
include ../../Makefile.include
$(eval $(call compile_template,-march=rv32i -mabi=ilp32 -DXLEN=$(XLEN)))
```
Explanation below is from ChatGPT.
>The eval function is used to evaluate a string as makefile code, and the call function is used to substitute the values of variables into a string. In this example, the compile_target function is being called with several arguments, and the result is being passed to eval to be evaluated as makefile code.
The arguments passed to the `compile_template` function are: `-march=rv32i`, `-mabi=ilp32`, and `-DXLEN=$(XLEN)`. These are options passed to the compiler, where `-march=rv32i` sets the target architecture to RISC-V 32-bit integer, `-mabi=ilp32` sets the target ABI to RISC-V ILP32, and `-DXLEN=$(XLEN)` defines the XLEN macro with the value of the XLEN variable.
Then it calls the defined function `compile_target` in `Makefile.include` in directory `riscv-arch-test/riscv-test-suite`
```bash=
define compile_template
$(work_dir_isa)/%.elf: $(src_dir)/%.S
$(V) echo "Compile $$(@)"
@mkdir -p $$(@D)
$(V) $(COMPILE_TARGET)
.PRECIOUS: $(work_dir_isa)/%.elf
endef
```
`COMPILE_TARGET` is the variable we mentioned before that compiles the set of testing code written in assembly.
### riscv-arch-test implement
Now, I try to run riscv-arch-test on FemtoRV-quark. Here is my target setting below.
link.ld is reference from `example-target` in `/riscv-target/example-target/env`.
```bash=
OUTPUT_ARCH( "riscv" )
ENTRY(rvtest_entry_point)
SECTIONS
{
. = 0x00000000;
.text.init : { *(.text.init) }
. = ALIGN(0x1000);
.text : { *(.text) }
. = ALIGN(0x1000);
.data : { *(.data) }
.data.string : { *(.data.string)}
.bss : { *(.bss) }
_end = .;
}
```
model_test.h is reference from rv32emu.
```bash=
#define RVMODEL_HALT \
add a7, x0, 93; \
add a0, x0, 0; \
ecall
#define RVMODEL_BOOT
#define RVTEST_RV32M
#define RVMODEL_DATA_BEGIN \
.align 4; \
.global begin_signature; \
begin_signature:
#define RVMODEL_DATA_END \
.align 4; \
.global end_signature; \
end_signature:
#define RVMODEL_IO_INIT
#define RVMODEL_IO_WRITE_STR(_SP, _STR)
#define RVMODEL_IO_CHECK()
#define RVMODEL_IO_ASSERT_GPR_EQ(_SP, _R, _I)
#define RVMODEL_IO_ASSERT_SFPR_EQ(_F, _R, _I)
#define RVMODEL_IO_ASSERT_DFPR_EQ(_D, _R, _I)
#define RVMODEL_SET_MSW_INT
#define RVMODEL_CLEAR_MSW_INT
#define RVMODEL_CLEAR_MTIMER_INT
#define RVMODEL_CLEAR_MEXT_INT
```
The following is my target device `makefile.include`.
```bash=
rv32c := 0
TARGET_SIM ?=\
verilator -DBENCH_VERILATOR --top-module femtoRV32_bench \
-I$(TARGETDIR)/RTL -I$(TARGETDIR)/RTL/PROCESSOR -I$(TARGETDIR)/RTL/DEVICES -I$(TARGETDIR)/RTL/PLL \
-CFLAGS '-I$(TARGETDIR)/SIM' -LDFLAGS '-lglfw -lGL' \
--cc --exe $(TARGETDIR)/SIM/sim_main.cpp $(TARGETDIR)/SIM/FPU_funcs.cpp $(TARGETDIR)/SIM/SSD1351.cpp $(TARGETDIR)/RTL/femtosoc_bench.v \
--trace-fst -Mdir $(WORK)/rv32i_m/I/obj_dir
# (make -f $(WORK)/rv32i_m/I/obj_dir/VfemtoRV32_bench.mk); \
# $(WORK)/rv32i_m/I/obj_dir/VfemtoRV32_bench
TARGET_FLAGS ?= $(RISCV_TARGET_FLAGS) -q
ifeq ($(shell command -v $(TARGET_SIM) 2> /dev/null),)
$(error Target simulator executable '$(TARGET_SIM)` not found)
endif
RISCV_GCC ?= $(RISCV_PREFIX)gcc
RISCV_OBJDUMP ?= $(RISCV_PREFIX)objdump
RISCV_OBJCOPY ?= $(RISCV_PREFIX)objcopy
RISCV_READELF ?= $(RISCV_PREFIX)readelf
RAM_SIZE ?= 65536
ifeq ($(rv32c),1)
RISCV_GCC_OPTS ?= -static -march=rv32imac_zicsr -mabi=ilp32 $(EXTRA_CFLAGS) -mcmodel=medany -g -fvisibility=hidden -nostdlib -nostartfiles -DXLEN=$(XLEN) $(RVTEST_DEFINES)
else
RISCV_GCC_OPTS ?= -static -march=rv32i -mabi=ilp32 $(EXTRA_CFLAGS) -mcmodel=medany -g -fvisibility=hidden -nostdlib -nostartfiles -DXLEN=$(XLEN) $(RVTEST_DEFINES)
endif
COMPILE_CMD=\
$$(RISCV_GCC) $(1) $$(RISCV_GCC_OPTS) \
-I$(ROOTDIR)/riscv-test-suite/env/ \
-I$(TARGETDIR)/$(RISCV_TARGET)/ \
-T$(TARGETDIR)/$(RISCV_TARGET)/link.ld $$< \
-o $$@; \
$$(RISCV_OBJCOPY) -O binary $$@ $$@.bin; \
$$(RISCV_OBJCOPY) -O binary -j .text $$@ $$@.imem.bin; \
$$(RISCV_OBJCOPY) -O binary -j .data $$@ $$@.dmem.bin; \
$$(RISCV_OBJCOPY) -O binary $$@ $$@.memory.bin; \
$(TO_HEX)
OBJ_CMD = $$(RISCV_OBJDUMP) $$@ -D > $$@.objdump; \
$$(RISCV_OBJDUMP) $$@ --source > $$@.debug; \
$$(RISCV_READELF) -a $$@ > $$@.readelf
COMPILE_TARGET=\
$(COMPILE_CMD); \
if [ $$$$? -ne 0 ] ; \
then \
echo "\e[31m$$(RISCV_GCC) failed for target $$(@) \e[39m" ; \
exit 1 ; \
fi ; \
$(OBJ_CMD); \
if [ $$$$? -ne 0 ] ; \
then \
echo "\e[31m $$(RISCV_OBJDUMP) failed for target $$(@) \e[39m" ; \
exit 1 ; \
fi ;
TO_HEX = \
$(FIRMWARE_DIR)/TOOLS/firmware_words $$(@) -ram $(RAM_SIZE) -max_addr $(RAM_SIZE) -out $$(*).hex
RUN_CMD=\
$(TARGET_SIM)
# cp $(*).hex $(FIRMWARE_DIR)/firmware.hex;
RUN_TARGET=\
cp $(*).elf.imem.bin imem.bin; cp $(*).elf.dmem.bin dmem.bin; cp $(*).elf.memory.bin memory.bin; \
cp $(*).hex input.hex; \
$(RUN_CMD) $(TARGET_FLAGS) $< 2> $@; mv trace.log $(*).trace.log; rm -f imem.bin dmem.bin memory.bin; \
mv dump.fst $(*).signature.output; if [ -f coverage.dat ]; then mv coverage.dat $(*)_cov.dat; fi; \
```
This is my makefile in directory `FIRMWARE` for calling `riscv-arch-test`.
```bash=
ARCH_TEST_DIR ?= tests/riscv-arch-test
ARCH_TEST_BUILD := $(ARCH_TEST_DIR)/Makefile
export RISCV_TARGET := tests/FemtoRV
export RISCV_PREFIX ?= $(RVTOOLCHAIN_BIN_DIR)/$(RVTOOLCHAIN_BIN_PREFIX)-
export TARGETDIR := $(shell pwd)
export XLEN := 32
export JOBS ?= -j
export FIRMWARE_DIR ?= $(TARGETDIR)/FIRMWARE
$(ARCH_TEST_BUILD):
git submodule update --init $(dir $@)
arch-test: $(ARCH_TEST_BUILD)
rm -rf $(TARGETDIR)/tests/riscv-arch-test/riscv-target/FemtoRV; \
cp -r $(TARGETDIR)/$(RISCV_TARGET)/. $(TARGETDIR)/tests/riscv-arch-test/riscv-target/FemtoRV;
ifndef RVTOOLCHAIN_DIR
$(error GNU Toolchain for RISC-V is required. Please check package installation)
endif
$(Q)$(MAKE) --quiet -C $(ARCH_TEST_DIR) clean
$(Q)$(MAKE) --quiet -C $(ARCH_TEST_DIR)
```
Include it in `/learn-fpga/FemtoRV`.
```bash=
# RISC-V Architecture Tests
include FIRMWARE/riscv-arch-test.mk
```
Now, I can run the command below to start `riscv-arch-test`, but run into an error.
```
make arch-test
```
:::spoiler Result
```bash=
cheng@cheng-VirtualBox:~/learn-fpga/FemtoRV$ make arch-test
Configuring for Linux x86_64
Makefile:29: warning: overriding recipe for target 'clean'
FIRMWARE/makefile.inc:170: warning: ignoring old recipe for target 'clean'
FIRMWARE/makefile.inc:98: warning: ignoring prerequisites on suffix rule definition
FIRMWARE/makefile.inc:102: warning: ignoring prerequisites on suffix rule definition
FIRMWARE/makefile.inc:106: warning: ignoring prerequisites on suffix rule definition
rm -rf /home/cheng/learn-fpga/FemtoRV/tests/riscv-arch-test/riscv-target/FemtoRV; \
cp -r /home/cheng/learn-fpga/FemtoRV/tests/FemtoRV/. /home/cheng/learn-fpga/FemtoRV/tests/riscv-arch-test/riscv-target/FemtoRV;
make --quiet -C tests/riscv-arch-test clean
============================ VARIABLE INFO ==================================
ROOTDIR: /home/cheng/learn-fpga/FemtoRV/tests/riscv-arch-test [origin: file]
WORK: /home/cheng/learn-fpga/FemtoRV/tests/riscv-arch-test/work [origin: file]
TARGETDIR: /home/cheng/learn-fpga/FemtoRV [origin: environment]
RISCV_TARGET: tests/FemtoRV [origin: environment]
XLEN: 32 [origin: environment]
RISCV_DEVICE: I [origin: file]
=============================================================================
make --quiet -C tests/riscv-arch-test
============================ VARIABLE INFO ==================================
ROOTDIR: /home/cheng/learn-fpga/FemtoRV/tests/riscv-arch-test [origin: file]
WORK: /home/cheng/learn-fpga/FemtoRV/tests/riscv-arch-test/work [origin: file]
TARGETDIR: /home/cheng/learn-fpga/FemtoRV [origin: environment]
RISCV_TARGET: tests/FemtoRV [origin: environment]
XLEN: 32 [origin: environment]
RISCV_DEVICE: I [origin: file]
=============================================================================
============================ VARIABLE INFO ==================================
ROOTDIR: /home/cheng/learn-fpga/FemtoRV/tests/riscv-arch-test [origin: file]
WORK: /home/cheng/learn-fpga/FemtoRV/tests/riscv-arch-test/work [origin: environment]
TARGETDIR: /home/cheng/learn-fpga/FemtoRV [origin: environment]
RISCV_TARGET: tests/FemtoRV [origin: command line]
XLEN: 32 [origin: environment]
RISCV_DEVICE: I [origin: command line]
=============================================================================
Compile /home/cheng/learn-fpga/FemtoRV/tests/riscv-arch-test/work/rv32i_m/I/add-01.elf
Compile /home/cheng/learn-fpga/FemtoRV/tests/riscv-arch-test/work/rv32i_m/I/addi-01.elf
Compile /home/cheng/learn-fpga/FemtoRV/tests/riscv-arch-test/work/rv32i_m/I/and-01.elf
Compile /home/cheng/learn-fpga/FemtoRV/tests/riscv-arch-test/work/rv32i_m/I/andi-01.elf
Compile /home/cheng/learn-fpga/FemtoRV/tests/riscv-arch-test/work/rv32i_m/I/auipc-01.elf
Compile /home/cheng/learn-fpga/FemtoRV/tests/riscv-arch-test/work/rv32i_m/I/beq-01.elf
Compile /home/cheng/learn-fpga/FemtoRV/tests/riscv-arch-test/work/rv32i_m/I/bge-01.elf
Compile /home/cheng/learn-fpga/FemtoRV/tests/riscv-arch-test/work/rv32i_m/I/bgeu-01.elf
Compile /home/cheng/learn-fpga/FemtoRV/tests/riscv-arch-test/work/rv32i_m/I/blt-01.elf
Compile /home/cheng/learn-fpga/FemtoRV/tests/riscv-arch-test/work/rv32i_m/I/bltu-01.elf
Compile /home/cheng/learn-fpga/FemtoRV/tests/riscv-arch-test/work/rv32i_m/I/bne-01.elf
Compile /home/cheng/learn-fpga/FemtoRV/tests/riscv-arch-test/work/rv32i_m/I/jal-01.elf
RAM SIZE=65536
Compile /home/cheng/learn-fpga/FemtoRV/tests/riscv-arch-test/work/rv32i_m/I/jalr-01.elf
LOAD ELF: /home/cheng/learn-fpga/FemtoRV/tests/riscv-arch-test/work/rv32i_m/I/auipc-01.elf
max address=4368
Code size: 1092 words ( total RAM size: 16384 words )
Occupancy: 6%
testing MAX_ADDR limit: 65536
max_addr OK
SAVE HEX: auipc-01.hex
Compile /home/cheng/learn-fpga/FemtoRV/tests/riscv-arch-test/work/rv32i_m/I/lb-align-01.elf
Compile /home/cheng/learn-fpga/FemtoRV/tests/riscv-arch-test/work/rv32i_m/I/lbu-align-01.elf
Compile /home/cheng/learn-fpga/FemtoRV/tests/riscv-arch-test/work/rv32i_m/I/lh-align-01.elf
Compile /home/cheng/learn-fpga/FemtoRV/tests/riscv-arch-test/work/rv32i_m/I/lhu-align-01.elf
RAM SIZE=Compile /home/cheng/learn-fpga/FemtoRV/tests/riscv-arch-test/work/rv32i_m/I/lui-01.elf
65536
LOAD ELF: /home/cheng/learn-fpga/FemtoRV/tests/riscv-arch-test/work/rv32i_m/I/add-01.elf
max address=18752
Code size: 4688 words ( total RAM size: 16384 words )
Occupancy: 28%
testing MAX_ADDR limit: 65536
max_addr OK
SAVE HEX: add-01.hex
RAM SIZE=65536
LOAD ELF: /home/cheng/learn-fpga/FemtoRV/tests/riscv-arch-test/work/rv32i_m/I/addi-01.elf
max address=14560
Code size: 3640 words ( total RAM size: 16384 words )
Occupancy: 22%
testing MAX_ADDR limit: 65536
max_addr OK
SAVE HEX: addi-01.hex
RAM SIZE=65536
LOAD ELF: /home/cheng/learn-fpga/FemtoRV/tests/riscv-arch-test/work/rv32i_m/I/andi-01.elf
max address=14560
Code size: 3640 words ( total RAM size: 16384 words )
Occupancy: 22%
testing MAX_ADDR limit: 65536
max_addr OK
SAVE HEX: andi-01.hex
RAM SIZE=65536
Compile /home/cheng/learn-fpga/FemtoRV/tests/riscv-arch-test/work/rv32i_m/I/lw-align-01.elf
LOAD ELF: /home/cheng/learn-fpga/FemtoRV/tests/riscv-arch-test/work/rv32i_m/I/and-01.elf
max address=18736
Code size: 4684 words ( total RAM size: 16384 words )
Occupancy: 28%
testing MAX_ADDR limit: 65536
max_addr OK
SAVE HEX: and-01.hex
Compile /home/cheng/learn-fpga/FemtoRV/tests/riscv-arch-test/work/rv32i_m/I/or-01.elf
RAM SIZE=65536
LOAD ELF: /home/cheng/learn-fpga/FemtoRV/tests/riscv-arch-test/work/rv32i_m/I/jalr-01.elf
max address=4256
Code size: 1064 words ( total RAM size: 16384 words )
Occupancy: 6%
testing MAX_ADDR limit: 65536
max_addr OK
SAVE HEX: jalr-01.hex
Compile /home/cheng/learn-fpga/FemtoRV/tests/riscv-arch-test/work/rv32i_m/I/ori-01.elf
Compile /home/cheng/learn-fpga/FemtoRV/tests/riscv-arch-test/work/rv32i_m/I/sb-align-01.elf
RAM SIZE=65536
LOAD ELF: /home/cheng/learn-fpga/FemtoRV/tests/riscv-arch-test/work/rv32i_m/I/lb-align-01.elf
max address=4256
Code size: 1064 words ( total RAM size: 16384 words )
Occupancy: 6%
testing MAX_ADDR limit: 65536
max_addr OK
SAVE HEX: lb-align-01.hex
RAM SIZE=65536
LOAD ELF: /home/cheng/learn-fpga/FemtoRV/tests/riscv-arch-test/work/rv32i_m/I/lh-align-01.elf
max address=4240
Code size: 1060 words ( total RAM size: 16384 words )
Occupancy: 6%
testing MAX_ADDR limit: 65536
max_addr OK
SAVE HEX: lh-align-01.hex
RAM SIZE=Compile /home/cheng/learn-fpga/FemtoRV/tests/riscv-arch-test/work/rv32i_m/I/sh-align-01.elf
65536
LOAD ELF: /home/cheng/learn-fpga/FemtoRV/tests/riscv-arch-test/work/rv32i_m/I/lbu-align-01.elf
max address=4240
Code size: 1060 words ( total RAM size: 16384 words )
Occupancy: 6%
testing MAX_ADDR limit: 65536
max_addr OK
SAVE HEX: lbu-align-01.hex
Compile /home/cheng/learn-fpga/FemtoRV/tests/riscv-arch-test/work/rv32i_m/I/sll-01.elf
RAM SIZE=Compile /home/cheng/learn-fpga/FemtoRV/tests/riscv-arch-test/work/rv32i_m/I/slli-01.elf
65536
LOAD ELF: /home/cheng/learn-fpga/FemtoRV/tests/riscv-arch-test/work/rv32i_m/I/lhu-align-01.elf
max address=4240
Code size: 1060 words ( total RAM size: 16384 words )
Occupancy: 6%
testing MAX_ADDR limit: 65536
max_addr OK
SAVE HEX: lhu-align-01.hex
Compile /home/cheng/learn-fpga/FemtoRV/tests/riscv-arch-test/work/rv32i_m/I/slt-01.elf
RAM SIZE=65536
LOAD ELF: /home/cheng/learn-fpga/FemtoRV/tests/riscv-arch-test/work/rv32i_m/I/lui-01.elf
max address=4368
Code size: 1092 words ( total RAM size: 16384 words )
Occupancy: 6%
testing MAX_ADDR limit: 65536
max_addr OK
SAVE HEX: lui-01.hex
RAM SIZE=65536
LOAD ELF: /home/cheng/learn-fpga/FemtoRV/tests/riscv-arch-test/work/rv32i_m/I/lw-align-01.elf
max address=4240
Code size: 1060 words ( total RAM size: 16384 words )
Occupancy: 6%
testing MAX_ADDR limit: 65536
max_addr OK
SAVE HEX: lw-align-01.hex
Compile /home/cheng/learn-fpga/FemtoRV/tests/riscv-arch-test/work/rv32i_m/I/slti-01.elf
Compile /home/cheng/learn-fpga/FemtoRV/tests/riscv-arch-test/work/rv32i_m/I/sltiu-01.elf
Compile /home/cheng/learn-fpga/FemtoRV/tests/riscv-arch-test/work/rv32i_m/I/sltu-01.elf
Compile /home/cheng/learn-fpga/FemtoRV/tests/riscv-arch-test/work/rv32i_m/I/sra-01.elf
RAM SIZE=65536
LOAD ELF: /home/cheng/learn-fpga/FemtoRV/tests/riscv-arch-test/work/rv32i_m/I/sb-align-01.elf
max address=4400
Code size: 1100 words ( total RAM size: 16384 words )
Occupancy: 6%
testing MAX_ADDR limit: 65536
max_addr OK
SAVE HEX: sb-align-01.hex
RAM SIZE=65536
LOAD ELF: /home/cheng/learn-fpga/FemtoRV/tests/riscv-arch-test/work/rv32i_m/I/sh-align-01.elf
max address=4400
Code size: 1100 words ( total RAM size: 16384 words )
Occupancy: 6%
testing MAX_ADDR limit: 65536
max_addr OK
SAVE HEX: sh-align-01.hex
Compile /home/cheng/learn-fpga/FemtoRV/tests/riscv-arch-test/work/rv32i_m/I/srai-01.elf
Compile /home/cheng/learn-fpga/FemtoRV/tests/riscv-arch-test/work/rv32i_m/I/srl-01.elf
RAM SIZE=65536
LOAD ELF: /home/cheng/learn-fpga/FemtoRV/tests/riscv-arch-test/work/rv32i_m/I/sll-01.elf
max address=4480
Code size: 1120 words ( total RAM size: 16384 words )
Occupancy: 6%
testing MAX_ADDR limit: 65536
max_addr OK
SAVE HEX: sll-01.hex
Compile /home/cheng/learn-fpga/FemtoRV/tests/riscv-arch-test/work/rv32i_m/I/srli-01.elf
Compile /home/cheng/learn-fpga/FemtoRV/tests/riscv-arch-test/work/rv32i_m/I/sub-01.elf
RAM SIZE=65536
LOAD ELF: /home/cheng/learn-fpga/FemtoRV/tests/riscv-arch-test/work/rv32i_m/I/slli-01.elf
max address=4464
Code size: 1116 words ( total RAM size: 16384 words )
Occupancy: 6%
testing MAX_ADDR limit: 65536
max_addr OK
SAVE HEX: slli-01.hex
Compile /home/cheng/learn-fpga/FemtoRV/tests/riscv-arch-test/work/rv32i_m/I/sw-align-01.elf
Compile /home/cheng/learn-fpga/FemtoRV/tests/riscv-arch-test/work/rv32i_m/I/xor-01.elf
RAM SIZE=65536
Compile /home/cheng/learn-fpga/FemtoRV/tests/riscv-arch-test/work/rv32i_m/I/xori-01.elf
LOAD ELF: /home/cheng/learn-fpga/FemtoRV/tests/riscv-arch-test/work/rv32i_m/I/beq-01.elf
max address=231728
Memory exceeded !
/home/cheng/learn-fpga/FemtoRV/FIRMWARE//TOOLCHAIN/xpack-riscv-none-elf-gcc-12.2.0-1-linux-x64/bin/riscv-none-elf-gcc failed for target /home/cheng/learn-fpga/FemtoRV/tests/riscv-arch-test/work/rv32i_m/I/beq-01.elf
make[3]: *** [Makefile:3: /home/cheng/learn-fpga/FemtoRV/tests/riscv-arch-test/work/rv32i_m/I/beq-01.elf] Error 1
make[3]: *** Waiting for unfinished jobs....
Compile /home/cheng/learn-fpga/FemtoRV/tests/riscv-arch-test/work/rv32i_m/I/fence-01.elf
RAM SIZE=65536
LOAD ELF: /home/cheng/learn-fpga/FemtoRV/tests/riscv-arch-test/work/rv32i_m/I/ori-01.elf
max address=14544
Code size: 3636 words ( total RAM size: 16384 words )
Occupancy: 22%
testing MAX_ADDR limit: 65536
max_addr OK
SAVE HEX: ori-01.hex
RAM SIZE=65536
LOAD ELF: /home/cheng/learn-fpga/FemtoRV/tests/riscv-arch-test/work/rv32i_m/I/sra-01.elf
max address=4480
Code size: 1120 words ( total RAM size: 16384 words )
Occupancy: 6%
testing MAX_ADDR limit: 65536
max_addr OK
SAVE HEX: sra-01.hex
RAM SIZE=65536
RAM SIZE= LOAD ELF: /home/cheng/learn-fpga/FemtoRV/tests/riscv-arch-test/work/rv32i_m/I/or-01.elf
max address=18752
Code size: 4688 words ( total RAM size: 16384 words )
Occupancy: 28%
testing MAX_ADDR limit: 65536
max_addr OK
SAVE HEX: or-01.hex
RAM SIZE=65536
LOAD ELF: /home/cheng/learn-fpga/FemtoRV/tests/riscv-arch-test/work/rv32i_m/I/bge-01.elf
65536
LOAD ELF: /home/cheng/learn-fpga/FemtoRV/tests/riscv-arch-test/work/rv32i_m/I/srai-01.elf
max address=4464
Code size: 1116 words ( total RAM size: 16384 words )
Occupancy: 6%
testing MAX_ADDR limit: 65536
max_addr OK
SAVE HEX: srai-01.hex
max address=235856
Memory exceeded !
/home/cheng/learn-fpga/FemtoRV/FIRMWARE//TOOLCHAIN/xpack-riscv-none-elf-gcc-12.2.0-1-linux-x64/bin/riscv-none-elf-gcc failed for target /home/cheng/learn-fpga/FemtoRV/tests/riscv-arch-test/work/rv32i_m/I/bge-01.elf
make[3]: *** [Makefile:3: /home/cheng/learn-fpga/FemtoRV/tests/riscv-arch-test/work/rv32i_m/I/bge-01.elf] Error 1
RAM SIZE=65536
LOAD ELF: /home/cheng/learn-fpga/FemtoRV/tests/riscv-arch-test/work/rv32i_m/I/srl-01.elf
max address=4480
Code size: 1120 words ( total RAM size: 16384 words )
Occupancy: 6%
testing MAX_ADDR limit: 65536
max_addr OK
SAVE HEX: srl-01.hex
RAM SIZE= RAM SIZE=65536
65536
LOAD ELF: /home/cheng/learn-fpga/FemtoRV/tests/riscv-arch-test/work/rv32i_m/I/srli-01.elf
max address=4480
Code size: 1120 words ( total RAM size: 16384 words )
Occupancy: 6%
testing MAX_ADDR limit: 65536
max_addr OK
SAVE HEX: srli-01.hex
LOAD ELF: /home/cheng/learn-fpga/FemtoRV/tests/riscv-arch-test/work/rv32i_m/I/blt-01.elf
max address=227616
Memory exceeded !
/home/cheng/learn-fpga/FemtoRV/FIRMWARE//TOOLCHAIN/xpack-riscv-none-elf-gcc-12.2.0-1-linux-x64/bin/riscv-none-elf-gcc failed for target /home/cheng/learn-fpga/FemtoRV/tests/riscv-arch-test/work/rv32i_m/I/blt-01.elf
make[3]: *** [Makefile:3: /home/cheng/learn-fpga/FemtoRV/tests/riscv-arch-test/work/rv32i_m/I/blt-01.elf] Error 1
RAM SIZE=65536
LOAD ELF: /home/cheng/learn-fpga/FemtoRV/tests/riscv-arch-test/work/rv32i_m/I/slt-01.elf
max address=18736
Code size: 4684 words ( total RAM size: 16384 words )
Occupancy: 28%
testing MAX_ADDR limit: 65536
max_addr OK
SAVE HEX: slt-01.hex
RAM SIZE= RAM SIZE=65536
LOAD ELF: /home/cheng/learn-fpga/FemtoRV/tests/riscv-arch-test/work/rv32i_m/I/bne-01.elf
max address=231728
Memory exceeded !
/home/cheng/learn-fpga/FemtoRV/FIRMWARE//TOOLCHAIN/xpack-riscv-none-elf-gcc-12.2.0-1-linux-x64/bin/riscv-none-elf-gcc failed for target /home/cheng/learn-fpga/FemtoRV/tests/riscv-arch-test/work/rv32i_m/I/bne-01.elf
make[3]: *** [Makefile:3: /home/cheng/learn-fpga/FemtoRV/tests/riscv-arch-test/work/rv32i_m/I/bne-01.elf] Error 1
65536
LOAD ELF: /home/cheng/learn-fpga/FemtoRV/tests/riscv-arch-test/work/rv32i_m/I/sw-align-01.elf
max address=4384
Code size: 1096 words ( total RAM size: 16384 words )
Occupancy: 6%
testing MAX_ADDR limit: 65536
max_addr OK
SAVE HEX: sw-align-01.hex
RAM SIZE=65536
LOAD ELF: /home/cheng/learn-fpga/FemtoRV/tests/riscv-arch-test/work/rv32i_m/I/slti-01.elf
max address=14544
Code size: 3636 words ( total RAM size: 16384 words )
Occupancy: 22%
testing MAX_ADDR limit: 65536
max_addr OK
SAVE HEX: slti-01.hex
RAM SIZE=65536
LOAD ELF: /home/cheng/learn-fpga/FemtoRV/tests/riscv-arch-test/work/rv32i_m/I/fence-01.elf
max address=4128
Code size: 1032 words ( total RAM size: 16384 words )
Occupancy: 6%
testing MAX_ADDR limit: 65536
max_addr OK
SAVE HEX: fence-01.hex
RAM SIZE=65536
LOAD ELF: /home/cheng/learn-fpga/FemtoRV/tests/riscv-arch-test/work/rv32i_m/I/bltu-01.elf
max address=306032
Memory exceeded !
/home/cheng/learn-fpga/FemtoRV/FIRMWARE//TOOLCHAIN/xpack-riscv-none-elf-gcc-12.2.0-1-linux-x64/bin/riscv-none-elf-gcc failed for target /home/cheng/learn-fpga/FemtoRV/tests/riscv-arch-test/work/rv32i_m/I/bltu-01.elf
make[3]: *** [Makefile:3: /home/cheng/learn-fpga/FemtoRV/tests/riscv-arch-test/work/rv32i_m/I/bltu-01.elf] Error 1
RAM SIZE=65536
LOAD ELF: /home/cheng/learn-fpga/FemtoRV/tests/riscv-arch-test/work/rv32i_m/I/sltiu-01.elf
max address=15104
Code size: 3776 words ( total RAM size: 16384 words )
Occupancy: 23%
testing MAX_ADDR limit: 65536
max_addr OK
SAVE HEX: sltiu-01.hex
RAM SIZE=65536
LOAD ELF: /home/cheng/learn-fpga/FemtoRV/tests/riscv-arch-test/work/rv32i_m/I/bgeu-01.elf
max address=301936
Memory exceeded !
/home/cheng/learn-fpga/FemtoRV/FIRMWARE//TOOLCHAIN/xpack-riscv-none-elf-gcc-12.2.0-1-linux-x64/bin/riscv-none-elf-gcc failed for target /home/cheng/learn-fpga/FemtoRV/tests/riscv-arch-test/work/rv32i_m/I/bgeu-01.elf
make[3]: *** [Makefile:3: /home/cheng/learn-fpga/FemtoRV/tests/riscv-arch-test/work/rv32i_m/I/bgeu-01.elf] Error 1
RAM SIZE=65536
LOAD ELF: /home/cheng/learn-fpga/FemtoRV/tests/riscv-arch-test/work/rv32i_m/I/sltu-01.elf
max address=19296
Code size: 4824 words ( total RAM size: 16384 words )
Occupancy: 29%
testing MAX_ADDR limit: 65536
max_addr OK
SAVE HEX: sltu-01.hex
RAM SIZE= RAM SIZE=65536
LOAD ELF: /home/cheng/learn-fpga/FemtoRV/tests/riscv-arch-test/work/rv32i_m/I/sub-01.elf
max address=18768
Code size: 4692 words ( total RAM size: 16384 words )
Occupancy: 28%
testing MAX_ADDR limit: 65536
max_addr OK
SAVE HEX: sub-01.hex
65536
LOAD ELF: /home/cheng/learn-fpga/FemtoRV/tests/riscv-arch-test/work/rv32i_m/I/xori-01.elf
max address=14576
Code size: 3644 words ( total RAM size: 16384 words )
Occupancy: 22%
testing MAX_ADDR limit: 65536
max_addr OK
SAVE HEX: xori-01.hex
RAM SIZE=65536
LOAD ELF: /home/cheng/learn-fpga/FemtoRV/tests/riscv-arch-test/work/rv32i_m/I/xor-01.elf
max address=18752
Code size: 4688 words ( total RAM size: 16384 words )
Occupancy: 28%
testing MAX_ADDR limit: 65536
max_addr OK
SAVE HEX: xor-01.hex
RAM SIZE=65536
LOAD ELF: /home/cheng/learn-fpga/FemtoRV/tests/riscv-arch-test/work/rv32i_m/I/jal-01.elf
max address=1753232
Memory exceeded !
/home/cheng/learn-fpga/FemtoRV/FIRMWARE//TOOLCHAIN/xpack-riscv-none-elf-gcc-12.2.0-1-linux-x64/bin/riscv-none-elf-gcc failed for target /home/cheng/learn-fpga/FemtoRV/tests/riscv-arch-test/work/rv32i_m/I/jal-01.elf
make[3]: *** [Makefile:3: /home/cheng/learn-fpga/FemtoRV/tests/riscv-arch-test/work/rv32i_m/I/jal-01.elf] Error 1
make[2]: *** [Makefile:84: simulate] Error 2
make[1]: *** [Makefile:65: all_variant] Error 2
make: *** [FIRMWARE/riscv-arch-test.mk:16: arch-test] Error 2
```
:::
There are several test code can't transform from elf to hex file. Here I list the failed test below.
```
bge-01.elf
beq-01.elf
blt-01.elf
bne-01.elf
bgeu-01.elf
bltu-01.elf
jal-01.elf
```
The similarities between them are they are all branch or jump instructions.
## Todo
- riscv-arch-test implement debug
- discuss the LUT decreasing method, analyze CSR support
## Reference
[learn-fpga](https://github.com/BrunoLevy/learn-fpga)
[Refernece 2](https://hackmd.io/@N9qHU_eLRvKyfDfJk8cDXA/Byj08q3jK)
[rv32emu](https://github.com/sysprog21/rv32emu)
[srv32](https://github.com/kuopinghsu/srv32)