diff --git a/README.md b/README.md index b2ce694..d056d92 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,8 @@ # RISCV(picorv32) baremetal on FPGA on Windows and Linux -## Building RISC-V from scratch, using Linux or WSL +## Cross-Compiling for RISCV on Linux or WSL for the DE0-NANO FPGA + +### 1. installation ```html sudo apt-get update sudo apt-get install autoconf automake autotools-dev curl python3 python3-pip libmpc-dev libmpfr-dev libgmp-dev gawk build-essential bison flex texinfo gperf libtool patchutils bc zlib1g-dev libexpat-dev ninja-build git cmake libglib2.0-dev @@ -14,7 +16,7 @@ sudo chown $USER /opt/riscv32im make -j$(nproc) ``` -## For other architectures or variations of RISC-V +#### For other architectures or variations of RISC-V | Command | ISA | |:---------------------------------------- |:-------- | |`./configure --with-arch=rv32i --prefix=/opt/riscv32i/ `| `RV32I `| @@ -22,12 +24,8 @@ make -j$(nproc) |`./configure --with-arch=rv32im --prefix=/opt/riscv32im/` | `RV32IM `| |`./configure --with-arch=rv32imc --prefix=/opt/riscv32imc/`| `RV32IMC `| -## Other Linux and Windows precompiled Toolchains - - https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack/releases/ for mingw64 - - https://gnutoolchains.com/risc-v/ - -# Build the firmware +### 2. Corss-Compiling C code for the RISCV picorv32 on WSL or on Linux. ```html git clone https://gitea.squirrelnut.synology.me:5001/FPGALover/RISCV_picorv32_fpga cd RISCV_picorv32_fpga/sw @@ -36,3 +34,183 @@ make firmware/firmware.fpga cp firmware/Memory.v_toplevel_memory_1_symbol* ../rtl/DE0-NANO ``` *Now you can compile or synthesize the FPGA harware using Quartus or any other Design tool* + +### 3. Syhtesize the project on Quartus. +Open Quartus, and run the synthesis of the system, the project you can find it under "\RISCV_picorv32_fpga\rtl\DE0-NANO", and the memories generated in binaries: +``` + $ ls -l ./rtl/DE0-NANO/ | grep "Memory" + Memory.v_toplevel_memory_1_symbol0.bin + Memory.v_toplevel_memory_1_symbol1.bin + Memory.v_toplevel_memory_1_symbol2.bin + Memory.v_toplevel_memory_1_symbol3.bin +``` +So everytime you want to change your RISCV C code(sw\firmware\main.c), you would need to generate Memories to load them to the embedded memories, or find a way to change their content during runtime. + +you can find that that these binaries are used by the file memory.v(xoro_top->Memory) which, on lines 32 to 35 of the Verilog description +``` + initial begin + $readmemb("Memory.v_toplevel_memory_1_symbol0.bin",memory_1_symbol0); + $readmemb("Memory.v_toplevel_memory_1_symbol1.bin",memory_1_symbol1); + $readmemb("Memory.v_toplevel_memory_1_symbol2.bin",memory_1_symbol2); + $readmemb("Memory.v_toplevel_memory_1_symbol3.bin",memory_1_symbol3); + end +``` + +## Cross-Compiling for RISCV on Windows + +### 1. Installation +You must download the latest RISCV precompiled binaries for your platform from: https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack/releases/ +in this case the architecture x64 for windows binaries(https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack/releases/download/v13.2.0-2/xpack-riscv-none-elf-gcc-13.2.0-2-darwin-x64.tar.gz), then extract these under the folder C:\riscv_precompiled\ + + Note: If you change the location where you installed the RISC-V precompiled binaries, you need to modify line 3 of the file \sw\Makefile. This will be explained further in this manual + +
+ + +### 2. Clone this repository +Open a CMD Clone this repository, or just simply download it somewhere on your hardrive. +```html +git clone https://gitea.squirrelnut.synology.me:5001/FPGALover/RISCV_picorv32_fpga +``` +### 3. Install Python +Before you can cross compile, you need to have Python installed on your windows machine, make sure you install Python2.7 or Python3, in case you install python3, you would need to modify the variable "PYTHON_VER" at the line # 8 of the file \sw\Makefile. Also make sure that your python is register under the *Path* enviroment variables + +### 4. Cross compile +Go to the directory RISCV_picorv32_fpga/sw using a CMD. + +```html +cd RISCV_picorv32_fpga/sw +``` +then write the command "make clean" to clean all the binaries downloaded with this repository, you should see: + +``` + > make clean + rm -vrf firmware/start.o firmware/irq.o firmware/print.o firmware/inch.o firmware/timer.o firmware/prng.o firmware/leds.o firmware/fftbench.o firmware/main.o \ + firmware/firmware.elf firmware/firmware.bin firmware/firmware.hex firmware/firmware.mif firmware/firmware.map firmware/Memory.v_toplevel_memory_1_symbol* + removed `firmware/start.o' + removed `firmware/irq.o' + removed `firmware/print.o' + removed `firmware/inch.o' + removed `firmware/timer.o' + removed `firmware/prng.o' + removed `firmware/leds.o' + removed `firmware/fftbench.o' + removed `firmware/main.o' + removed `firmware/firmware.elf' + removed `firmware/firmware.bin' + removed `firmware/firmware.hex' + removed `firmware/firmware.mif' + removed `firmware/firmware.map' + removed `firmware/Memory.v_toplevel_memory_1_symbol0.bin' + removed `firmware/Memory.v_toplevel_memory_1_symbol1.bin' + removed `firmware/Memory.v_toplevel_memory_1_symbol2.bin' + removed `firmware/Memory.v_toplevel_memory_1_symbol3.bin' +``` + +after cleaning, you can simple write the command "make firmware/firmware.fpga" and you will see: + +``` + > make firmware/firmware.fpga + C:\riscv_precompiled/bin/riscv-none-elf-gcc -c -march=rv32im -o firmware/start.o firmware/start.S + C:\riscv_precompiled/bin/riscv-none-elf-gcc -c -march=rv32im -Os -W --std=c99 -Wall -Wextra -Wshadow -Wundef -Wpointer-arith -Wcast-qual -Wcast-align -Wwrite-strings -Wredundant-decls -Wstrict-prototypes -Wmissing-prototypes -pedantic -ffreestanding -nostdlib -o firmware/irq.o firmware/irq.c + C:\riscv_precompiled/bin/riscv-none-elf-gcc -c -march=rv32im -Os -W --std=c99 -Wall -Wextra -Wshadow -Wundef -Wpointer-arith -Wcast-qual -Wcast-align -Wwrite-strings -Wredundant-decls -Wstrict-prototypes -Wmissing-prototypes -pedantic -ffreestanding -nostdlib -o firmware/print.o firmware/print.c + C:\riscv_precompiled/bin/riscv-none-elf-gcc -c -march=rv32im -Os -W --std=c99 -Wall -Wextra -Wshadow -Wundef -Wpointer-arith -Wcast-qual -Wcast-align -Wwrite-strings -Wredundant-decls -Wstrict-prototypes -Wmissing-prototypes -pedantic -ffreestanding -nostdlib -o firmware/inch.o firmware/inch.c + C:\riscv_precompiled/bin/riscv-none-elf-gcc -c -march=rv32im -Os -W --std=c99 -Wall -Wextra -Wshadow -Wundef -Wpointer-arith -Wcast-qual -Wcast-align -Wwrite-strings -Wredundant-decls -Wstrict-prototypes -Wmissing-prototypes -pedantic -ffreestanding -nostdlib -o firmware/timer.o firmware/timer.c + C:\riscv_precompiled/bin/riscv-none-elf-gcc -c -march=rv32im -Os -W --std=c99 -Wall -Wextra -Wshadow -Wundef -Wpointer-arith -Wcast-qual -Wcast-align -Wwrite-strings -Wredundant-decls -Wstrict-prototypes -Wmissing-prototypes -pedantic -ffreestanding -nostdlib -o firmware/prng.o firmware/prng.c + C:\riscv_precompiled/bin/riscv-none-elf-gcc -c -march=rv32im -Os -W --std=c99 -Wall -Wextra -Wshadow -Wundef -Wpointer-arith -Wcast-qual -Wcast-align -Wwrite-strings -Wredundant-decls -Wstrict-prototypes -Wmissing-prototypes -pedantic -ffreestanding -nostdlib -o firmware/leds.o firmware/leds.c + C:\riscv_precompiled/bin/riscv-none-elf-gcc -c -march=rv32im -Os -W --std=c99 -Wall -Wextra -Wshadow -Wundef -Wpointer-arith -Wcast-qual -Wcast-align -Wwrite-strings -Wredundant-decls -Wstrict-prototypes -Wmissing-prototypes -pedantic -ffreestanding -nostdlib -o firmware/fftbench.o firmware/fftbench.c + firmware/fftbench.c: In function 'fft_bench': + firmware/fftbench.c:109:9: warning: variable 'slices' set but not used [-Wunused-but-set-variable] + 109 | int slices; + | ^~~~~~ + firmware/fftbench.c:108:9: warning: unused variable 'slice' [-Wunused-variable] + 108 | int slice; + | ^~~~~ + firmware/fftbench.c:107:9: warning: variable 'lastLevel' set but not used [-Wunused-but-set-variable] + 107 | int lastLevel; + | ^~~~~~~~~ + firmware/fftbench.c:106:9: warning: variable 'firstLevel' set but not used [-Wunused-but-set-variable] + 106 | int firstLevel; + | ^~~~~~~~~~ + firmware/fftbench.c:105:12: warning: unused variable 'slen' [-Wunused-variable] + 105 | int s, slen; + | ^~~~ + firmware/fftbench.c:105:9: warning: unused variable 's' [-Wunused-variable] + 105 | int s, slen; + | ^ + firmware/fftbench.c: In function 'butterflies': + firmware/fftbench.c:266:27: warning: declaration of 'bx' shadows a global declaration [-Wshadow] + 266 | void butterflies(int32_t* bx, int32_t* by, int32_t firstLevel, int32_t lastLevel, int32_t slices, int32_t slen) { + | ^ + firmware/fftbench.c:65:16: note: shadowed declaration is here + 65 | static int32_t bx[FFT_SIZE]; + | ^~ + firmware/fftbench.c:266:40: warning: declaration of 'by' shadows a global declaration [-Wshadow] + 266 | void butterflies(int32_t* bx, int32_t* by, int32_t firstLevel, int32_t lastLevel, int32_t slices, int32_t slen) { + | ^ + firmware/fftbench.c:66:16: note: shadowed declaration is here + 66 | static int32_t by[FFT_SIZE]; + | ^~ + C:\riscv_precompiled/bin/riscv-none-elf-gcc -c -march=rv32im -Os -W --std=c99 -Wall -Wextra -Wshadow -Wundef -Wpointer-arith -Wcast-qual -Wcast-align -Wwrite-strings -Wredundant-decls -Wstrict-prototypes -Wmissing-prototypes -pedantic -ffreestanding -nostdlib -o firmware/main.o firmware/main.c + C:\riscv_precompiled/bin/riscv-none-elf-gcc -Os -ffreestanding -nostdlib -o firmware/firmware.elf \ + -Wl,-Bstatic,-T,firmware/sections.lds,-Map,firmware/firmware.map,--strip-debug \ + firmware/start.o firmware/irq.o firmware/print.o firmware/inch.o firmware/timer.o firmware/prng.o firmware/leds.o firmware/fftbench.o firmware/main.o -lgcc + c:/riscv_precompiled/bin/../lib/gcc/riscv-none-elf/12.3.0/../../../../riscv-none-elf/bin/ld: warning: firmware/firmware.elf has a LOAD segment with RWX permissions + chmod -x firmware/firmware.elf + C:\riscv_precompiled/bin/riscv-none-elf-objcopy -O binary firmware/firmware.elf firmware/firmware.bin + chmod -x firmware/firmware.bin + python firmware/makehex.py firmware/firmware.bin 16384 firmware > firmware/firmware.hex + python firmware/makebin.py firmware/firmware.hex 16384 > firmware/firmware.fpga +``` + Note: if you changed the location of the precompiled RISCV binaries, you need to modify the variable "RISCV_GNU_TOOLCHAIN_INSTALL_PREFIX" of file "\sw\Makefile" at the line # 3 + +if you built the files successfuly, you would able to see under the folder "sw\firmware" the memories binaries: +``` + >ls firmware + custom_ops.S leds.o + fftbench.c main.c + fftbench.o main.o + firmware.bin makebin.py + firmware.elf makehex.py + firmware.fpga makemif.py + firmware.h Memory.v_toplevel_memory_1_symbol0.bin + firmware.hex Memory.v_toplevel_memory_1_symbol1.bin + firmware.map Memory.v_toplevel_memory_1_symbol2.bin + firmware.mif Memory.v_toplevel_memory_1_symbol3.bin + firmware0.hex print.c + firmware1.hex print.o + firmware2.hex prng.c + firmware3.hex prng.o + inch.c sections.lds + inch.o start.o + irq.c start.S + irq.o timer.c + leds.c timer.o +``` + +### 4.Syhtesize the project on Quartus. +Open Quartus, and run the synthesis of the system, the project you can find it under "RISCV_picorv32_fpga\rtl\DE0-NANO", and the memories generated in binaries: +``` + Memory.v_toplevel_memory_1_symbol0.bin + Memory.v_toplevel_memory_1_symbol1.bin + Memory.v_toplevel_memory_1_symbol2.bin + Memory.v_toplevel_memory_1_symbol3.bin +``` +So everytime you want to change your RISCV C code(sw\firmware\main.c), you would need to generate Memories to load them to the embedded memories, or find a way to change their content during runtime. + +you can find that that these binaries are used by the file memory.v(xoro_top->Memory) which, on lines 32 to 35 of the Verilog description +``` + initial begin + $readmemb("Memory.v_toplevel_memory_1_symbol0.bin",memory_1_symbol0); + $readmemb("Memory.v_toplevel_memory_1_symbol1.bin",memory_1_symbol1); + $readmemb("Memory.v_toplevel_memory_1_symbol2.bin",memory_1_symbol2); + $readmemb("Memory.v_toplevel_memory_1_symbol3.bin",memory_1_symbol3); + end +``` + + +## Other Linux and Windows precompiled Toolchains + - https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack/releases/ for mingw64 + - https://gnutoolchains.com/risc-v/ +