Push Button FPGA Toolchains

Overview

I created stages for the Calyx toolchain driver fud that linked together Python and Bash scripts with Xilinx tools to enable the easy execution of Calyx programs on FPGAs. This work could not have happened without the help of Rachit Nigam and Adrian Sampson.


In trying to get Verilog AXI interfaces to interface with XRT it made sense to have a system that allowed for rapid testing of iterations of my AXI interface. Ideally, we would have a simple system to either simulate programs or actually execute them on our Xilinx Alveo U50.

Unfortunately, going from a program to doing either of the above was enough of a chore that it required an entire page of dedicated documentation detailing environment variables that needed to be set and flags that needed to be passed in in order to have any hope of getting programs to execute properly.

To this end, I worked on creating fud stages that would simplify the process of running programs on our FPGA.

fud is a command line tool that pipelines together the various tools and stages needed to convert Calyx programs into desired output programs. In our case, we wanted to go from Calyx to xclbins to actually simulating/executing.

The fud stage I created parsed json files into inputs to programs, and utilized PYNQ to run these programs on hardware.

The work involved creating custom bash and python scripts, integrating said scripts into existing tools, diving into the documentation of PYNQ and integrating that as well, and expanding configuration options to correctly set environment variables and pass in flags as appropriate.

The final product allows us to run programs in two steps.

  1. Create an xclbin (equivalent to compiling an executable via something like gcc):
fud exec source-program.futil -o output-file.xclbin --to xclbin
  1. Execute said xclbin on an FPGA (equivalent to running an exectuable)
fud exec some-output.xclbin --from xclbin --to fpga -s fpga.data program-input.data

For a very simple dot product program, compiling ends up looking something like this:

And we can then execute the output file dot-product-2.xclbin. The output details the state of the memories defined in the original dot-product program at the end of execution. Namely, we can see the values of our inputs A and B, and v contains the result of our dot product.