Deep Dive into RISC-V … on FPGA

Part 1

I was interested in exploring the RISC-V architecture and what possible use I could make of it.

Did a little research and when it looked like the FPGA path could be the best option for me, I collected available RISC-V FPGA cores data, few would fit one on the FPGA’s I have, then I also found a project who had already done it.

So I implemented an existing RISC-V SoC on a Spartan-6 FPGA, a Pano Logic G2 board, using the LiteX VexRISC-V build environment and code, built using RISC-V cross compiler, connect the JTAG to the board flash the RISC-V to the FPGA and Linux to the NAND Flash.

Local storage is a tiny RAM (128MB), network is up and running and a serial console over DVI/VGA pins to a FT2232 (FTDI) serial (5V) to USB converter to manage the system when needed, this is enough to automate a boot, download at boot time or build in an application to be able to get online and start working.

It’s very fast, boots in a few seconds and connect to network, there is of course not so much space left on the flash to store any large application, but as a PoC it’s perfect and a larger board with faster FPGA and larger NAND, it will be even more useful as embedded system application platform.

pdp1145: ELF 32-bit LSB executable, UCB RISC-V, version 1 (SYSV), statically linked, with debug_info, not stripped

The test program (PDP1145) is transferred to the Linux by a wget to a FTP server.

Then I compare code from Intel platform and notice the execution time on an Haswell 3.20 GHz did in .20s and the RISC-V on 125MHz FPGA did it in .23s, what is the reason? Is the Intel that slow uncached? Or is it an architectural difference? Neither, on Linux PC it’s the disk load into memory that takes most of the time, after this is done once, it’s in memory and cached, while on the FPGA Linux and the loaded binary sits in RAM and has no load time.

Power on FPGA and the RISC-V boot Linux

Requesting system reboot
[13146537.373130] reboot: Restarting system

    __   _ __      _  __
   / /  (_) /____ | |/_/
  / /__/ / __/ -_)>  <
 /____/_/\__/\__/_/|_|

Build your hardware, easily!

(c) Copyright 2012-2020 Enjoy-Digital
(c) Copyright 2007-2015 M-Labs

BIOS built on May 12 2020 15:04:59
BIOS CRC passed (bd25700e)

Migen git sha1: 19d5eae
LiteX git sha1: 61473830

–=============== SoC ==================–
CPU: VexRiscv @ 50MHz
ROM: 32KB
SRAM: 32KB
L2: 8KB
MAIN-RAM: 65536KB

–========== Initialization ============–
Ethernet init…
Initializing SDRAM…
SDRAM now under hardware control
Memtest OK
Memspeed Writes: 122Mbps Reads: 163Mbps

–============== Boot ==================–
Booting from serial…
Press Q or ESC to abort boot completely.
sL5DdSMmkekro
Timeout
Loading Image from flash…
Copying 5369452 bytes from 0x20440000 to 0x40000000…
Loading rootfs.cpio from flash…
Copying 4063744 bytes from 0x209c0000 to 0x40800000…
Loading rv32.dtb from flash…
Copying 2096 bytes from 0x20410000 to 0x41000000…
Loading emulator.bin from flash…
Copying 2992 bytes from 0x20414000 to 0x41100000…
Executing booted program at 0x41100000

–============= Liftoff! ===============–
*** VexRiscv BIOS ***
*** Supervisor ***

——-8< ——–

Welcome to Buildroot
buildroot login: root
                __   _
               / /  (_)__  __ ____ __
              / /__/ / _ \/ // /\ \ /
             /____/_/_//_/\_,_//_\_\
                   / _ \/ _ \
   __   _ __      _\___/_//_/ __         ___  _
  / /  (_) /____ | |/_/__| | / /____ __ / _ \(_)__ _____  __
 / /__/ / __/ -_)>  </___/ |/ / -_) \ // , _/ (_-</ __/ |/ /
/____/_/\__/\__/_/|_|    |___/\__/_\_\/_/|_/_/___/\__/|___/

 32-bit VexRiscv CPU with MMU integrated in a LiteX SoC running on a Pano G2

Again using the PDP1145 diagnostics as test case, enough complicated and used many times on various PoC’s to evaluate capability and performance, so let’s time the PDP1145 diagnostics.

root@buildroot:~# time ./pdp1145
0 0 0 0 0 0 0 0 0 2 00 0 0 1 0 0 7 6 0 0 00 2 0 6 352
T1
T2
T3
getting new address 352
T4
T5

T1
T2
T3
getting new address 170
T4
T5

load BR 4 123321
T2
T3
getting new address 70
0 0 0 0 0 0 0 0 0 0 00 6 0 2 0 0 0 7 0 0 00 0 0 0 153
T4
T5

Elapsed time
real 0m 0.23s
user 0m 0.03s
sys 0m 0.19s

Next up is an attempt to run PDP1145 as Bare Metal on the RISC-V FPGA, no Linux!

References:

The Linux on Pano G2: https://github.com/skiphansen/panog2_linux

Part 2

Bare Metal

A RISC-V model riscv32i_spartan6 is used for the Bare Metal SoC evaluation, the PDP1145 is compiled as a Bare Metal ELF image and loaded directly from USB/Serial (FTDI), as still in developer/prototype/test mode it provides a quick way to make change, compile and run.

The RISC-V SoC provides a UART that is mapped to I2C pins on the is used as console and debug output, while performing the functional testing

pl@pl-virtual-machine:~/fpga/fpga_test_soc/src_c$ make
# Compiling main.c
# Building pdp1145
# Building pdp1145.lst
pl@pl-virtual-machine:~/fpga/fpga_test_soc/src_c$ make run
../run.py -d /dev/ttyUSB0 -b 1000000 -f  build.riscv.pdp1145/pdp1145 
/home/pl/fpga/fpga_test_soc/run/poke.py -t uart -d /dev/ttyUSB0 -b 1000000 -a 0xF0000000 -v 0x0
/home/pl/fpga/fpga_test_soc/run/load.py -t uart -d /dev/ttyUSB0 -b 1000000 -f build.riscv.pdp1145/pdp1145 -p ''
ELF: Loading 0x0 - size 42KB
 |XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX| 100.0% 
/home/pl/fpga/fpga_test_soc/run/console-uart.py -t uart -d /dev/ttyUSB0 -b 1000000 -f build.riscv.pdp1145/pdp1145
																		
T1
A/ B/ BA/
ALU/ SHFR/
PCA/ PCB/
SR/ DR/
BR/ IR/
T2
A/ B/ BA/
ALU/ SHFR/
PCA/ PCB/
SR/ DR/
BR/ IR/
T3
getting new address 
	BEND (TODO)
	BRQ STROBE (TODO)
																		
A/ B/ BA/
ALU/ SHFR/
PCA/ PCB/
SR/ DR/
BR/ IR/
T4
A/ B/ BA/
ALU/ SHFR/
PCA/ PCB/
SR/ DR/
BR/ IR/
T5
A/ B/ BA/
ALU/ SHFR/
PCA/ PCB/
SR/ DR/
BR/ IR/
----------
T1
A/ B/ BA/
ALU/ SHFR/
PCA/ PCB/
SR/ DR/
BR/ IR/
T2
A/ B/ BA/
ALU/ SHFR/
PCA/ PCB/
SR/ DR/
BR/ IR/
	INTR PAUSE
T3
getting new address 
																		
A/ B/ BA/
ALU/ SHFR/
PCA/ PCB/
SR/ DR/
BR/ IR/
T4
A/ B/ BA/
ALU/ SHFR/
PCA/ PCB/
SR/ DR/
BR/ IR/
T5
A/ B/ BA/
ALU/ SHFR/
PCA/ PCB/
SR/ DR/
BR/ IR/
----------
T1
load BR  
A/ B/ BA/
ALU/ SHFR/
PCA/ PCB/
SR/ DR/
BR/ IR/
T2
A/ B/ BA/
ALU/ SHFR/
PCA/ PCB/
SR/ DR/
BR/ IR/
T3
getting new address 
																		
A/ B/ BA/
ALU/ SHFR/
PCA/ PCB/
SR/ DR/
BR/ IR/
T4
A/ B/ BA/
ALU/ SHFR/
PCA/ PCB/
SR/ DR/
BR/ IR/
T5
A/ B/ BA/
ALU/ SHFR/
PCA/ PCB/
SR/ DR/
BR/ IR/
----------
T1
load BR  
A/ B/ BA/
ALU/ SHFR/
PCA/ PCB/
SR/ DR/
BR/ IR/

Leave a comment