--- 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/) ![](https://i.imgur.com/oxY0Jd1.png) - 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. ![](https://i.imgur.com/C8QwAmw.png) ## 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)