My introduction to RISC-V architecture programming came at the 2019 Hackaday Superconference. The event featured a keynote speech by Dr. Megan Wachs, VP of engineering at SiFive, which makes RISC-V-based silicone. I had some knowledge of FPGAs (field programmable gate arrays) and the RISC-V architecture — RISC-V is Berkeley’s fifth attempt at a Reduced Instruction Set Computing architecture (pronounced “risk five") — but no actual experience with either.
To facilitate hands-on learning and experimentation, Hackaday gave out programmable RISC-V development modules as badges. They also gave out secondary badges based on CircuitPython, which are configured with just a simple text editor. While I customized that badge, the main FPGA board was left idle for longer than I’d like to admit. Now I’ve finally revisited this RISC-V device to see if I can print out “Hello World,” or some variation on that theme.
FPGA Programming Toolchains & Setup
Naturally, programming this FPGA-based RISC-V badge requires a bit more yak shaving than its CircuitPython counterpart. The good news is that there are programming toolchains for Linux, MacOSX, Windows, and as a Docker image, available via the intro GitHub page. I used the "Windows Ten Minute Setup" variation.
It took me longer than 10 minutes to set everything up, but the instructions lay out how to get this done pretty well — even for someone who is new to this world. It’s certainly helpful to have some experience with the Bash shell, but I’m no expert and it was easy enough to stumble through.
RISC-V Programming Tutorial
As you follow those full instructions, here are a few tips for this particular process. Your RISC-V FPGA “hello world” may be on somewhat different hardware, but a few of these tips are generally applicable:
- You can paste into Git Bash, but Ctrl+V will not work. Just right-click and select paste. A different keyboard shortcut is available for this if you prefer: Shift+Ins.
- On Step E, make a .bashrc file in the home directory by entering nano ~/.bashrc. Copy/paste the needed lines in, but notice on the second line that the version may be different than what’s stated there. Mine was v1.1.6.9, based on the latest toolchain version found here.Ctrl+X exits the nano text editor.
- In step F, the Git Bash shell gave me some “feedback” about cygwin DLL, after trying to copy app-helloworld with cp -r. This happened even after finding only one copy with a search, and restarting, as suggested. I instead tried the Windows File Manager, which did the operation with no problem. Generally speaking, don’t be afraid to use the Windows GUI and Bash in tandem during this process.
- You can open Makefile, .bashrc, etc. with Notepad++ for editing.
- Running make may give you a warning about no /tmp folder, but it will still generate the proper files.
- If you need to change and recompile your program, delete the .elf, .map, and .sym files, input your changes, and run make again to regenerate these files.
With an .elf file compiled from the “app-helloworld” template, modified with my information, I took my first step into creating a C program that runs on a RISC-V processor. I then loaded this file on the badge via a Micro-USB cable — an easy task as it enumerates as USB mass storage when plugged in. After a power cycle, this new file showed up as a runnable option on the boot screen.
I also modified the “app-mynameis” C program and compiled it. The background image can also be changed with a photo editing program, allowing it to act as a very nice badge. Perhaps I’ll use it for a live event at some point.
RISC-V and FPGA Implementation
While most readers won’t program the exact same badge module I did here, it’s entirely possible that an attendee or two is reading this post. If that’s you, and you haven’t gotten into it, I’d highly suggest that you do. With the toolchain installed, it’s actually quite easy to compile a program. One general lesson we can learn here is that if a conference announcement asks you to have certain tools installed, go ahead and do it.
More specifically though, it’s neat to have compiled my first programs for the RISC-V processor, which incidentally is running on an FPGA. This means that the onboard Lattice LFE5U-45F FPGA is set up not to emulate, but to become two RISC-V CPUs on a circuit level, which executes the compiled C code. In addition to the CPUs, there’s an initial program loader, and even a PIC processor onboard to handle low-level duties like blinking LEDs. To clarify, there’s no separate PIC chip; the FPGA simply uses some of its resources to add on a PIC.
An important distinction when working with this FPGA is that C the program I wrote (or modified) wasn’t actually swapping gates around in the Lattice board. Instead, it creates a file that is transferred into storage on the roughly Game Boy-shaped badge/development module, to be run by the device’s FPGA RISC-V processors. In theory, the RISC-V processors on the Lattice board could be turned into something else, or added onto via its modular ISA design — though that would take a bit more effort.
Learning FPGA Programming
The whole concept is a lot to get your head around. Just as Neo was told “there is no spoon” in The Matrix, in the FPGA world, “there is no PIC,” and “there is no RISC-V processor.” Yet, for all intents and purposes these two processors do exist, analogous to Cypher’s perfectly simulated steak that was still “juicy and delicious.” I’m not sure if the world of FPGAs and open-source RISC-V toolchains would be stepping into the real world or out of it, but as this technology becomes more and more prevalent, it will make a wide variety of new innovations possible.