The FPGA-related tools
Up to this point, only C code was shown, which reflects what’s involved in developing an HLS-oriented application. There are however other players in the process, that have an important role in making all this work. Fortunately, only a shallow awareness of these is necessary. Nevertheless, it’s time to present the complete machinery. This page is intended as an overview, with no particular do-this do-that.
How it works
The essence of HLS is that a certain C/C++/SystemC function (referred to as the top-level function) is translated (”synthesized”), along with the functions and methods it calls, into state machines and logic building blocks. The result of this translation is some text files written in a hardware description language (HDL), namely Verilog (the VHDL output is disregarded here). These text files are then fed into software (the "main" Vivado suite) which turns them and some other files into a binary, which programs the FPGA to perform the logic behavior described by the HDL files.
A program runs on the host, which sends data for processing to the synthesized function, and retrieves its results.
In the suggested use of Xillybus with HLS, a wrapper function consists of some simple C code which grabs the data that was sent from the host and reorganizes it as necessary (possibly casting the types, putting the data in arrays or data structures etc.). The wrapper then calls the user-defined function. When that function returns, the wrapper function fetches the interesting data produced by the user-defined function, and organizes it for transmission to the host.
The wrapper function, the user-defined function, and any functions or methods the latter may call, are all synthesized together by a single run of the HLS tool. The seemingly sequential operations of the C/C++ code are pipelined by HLS optimization when possible. As a result, the wrapper function may accept new data for processing before the user-defined function has finished handling the previous set. Effectively, the user-defined function may handle several “calls” at once, as several sets of input data travels through the pipeline created by HLS.
Once the FPGA is programmed (or “configured” as FPGA people call it), the synthesized function runs over and over again, as if it was called in an infinite loop. There are several ways to transport data for the function’s arguments and its result data and return value. In the setting described here, the data is transported between the logic and host through data pipes, like pipes between processes.
Tools interaction (C and Verilog)
Two toolchains are involved in generating the binary bitfile for programming the logic fabric of the FPGA (or PL part on Zynq processors).
- Vivado, which is the mainstream tool used to implement FPGA designs. The programming languages used with this toolchain are Verilog and/or VHDL, which are well-established languages for describing logic.
- Vivado HLS, a relatively new tool, taking C/C++ code and translating it into a set of Verilog or VHDL files, which can be used as input to Vivado.
Accordingly, the workflow of going from a C/C++ function to a bitfile involves following steps:
- Running Vivado HLS on the C/C++ function
- Exporting the output of HLS into a DCP file
- Including the DCP file created by Vivado HLS in an Vivado project
- Launching Vivado on the latter project
- Verifying that the implementation generated a proper bitfile
Unfortunately, there is currently no automated tool available by Xilinx for running this through in one go, even though it’s technically possible. It’s possible to write a script, but this requires a substantial understanding of each tool. A general-purpose script would be difficult to maintain and document, and is hence not offered either.
Xillybus IP core and driver
The Xillybus IP core and host driver are used as the framework in the coprocessing project, in two ways:
- The data transport between the host program and the wrapper function (and hence the synthesized function as well) is done transparently by Xillybus.
- The demo bundle for the FPGA is used as a starting point for the Vivado project. As this bundle is set up to work out of the box, it frees its user from taking care of the essentials of bringing up a stable FPGA design.
The initial milestone of setting of the working environment is therefore a trivial loopback test with Xillybus. As shown next, this involves downloading and installing a heavy piece of Xilinx software, downloading and implementing the FPGA bundle (or Xillinux for Zynq) with Xilinx’ tools, and installing Xillybus’ driver on the host. Once that milestone is reached, the attention can be shifted to developing in C and recurring tasks with Xilinx’ tools.