RISCV_picorv32_fpga/README.md

227 lines
47 KiB
Markdown

# RISCV(picorv32) baremetal on FPGA on Windows and Linux
## 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
git clone https://github.com/riscv/riscv-gnu-toolchain
cd riscv-gnu-toolchain/
mkdir build/
cd build
sudo mkdir /opt/riscv32im
sudo chown $USER /opt/riscv32im
../configure --with-arch=rv32im --prefix=/opt/riscv32im
make -j$(nproc)
```
#### For other architectures or variations of RISC-V
| Command | ISA |
|:---------------------------------------- |:-------- |
|`../configure --with-arch=rv32i --prefix=/opt/riscv32i/ `| `RV32I `|
|`../configure --with-arch=rv32ic --prefix=/opt/riscv32ic/ `| `RV32IC `|
|`../configure --with-arch=rv32im --prefix=/opt/riscv32im/` | `RV32IM `|
|`../configure --with-arch=rv32imc --prefix=/opt/riscv32imc/`| `RV32IMC `|
### 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
make clean
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\
<span style="color:red">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 </span>
<span style="color:magenta">Your precompiled binaries should look like this on your file system:</span>
<br>
<img src="data:image/png;base64,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"
style="float: left; margin-right: 10px;" />
### 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
open a CMD and check that you can summon python when you type "python" or "python3", just make sure it correspond to the Makefile name
```
> python
Python 3.11.7 (main, Dec 7 2023, 09:09:57) [GCC UCRT 13.2.0 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> exit()
```
### 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
```
<span style="color:red">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</span>
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 just in case
- https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack/releases/ for mingw64
- https://gnutoolchains.com/risc-v/
under this repo you can also find some prebuilt binaries for Linux and Windows, in case any one of the servers was down, or you could not build it.