Walkthrough4: High Level Synthesis Example¶
This page already assumes that you are familiar with building and uploading firmware to an FPGA. Instructions for creating your own repository for EMP payloads and modifying it is also advisable:
getting started with EMP: Step 3: Build firmware or run simulation, then:
building from your own repo: Walkthrough1: creating your own repository from scratch
algorithm modification to add 5: Walkthrough2: First payload modifications and buffer manipulation - “Plus5”
High Level Synthesis¶
High Level Synthesis (HLS) is a method of generating firmware (RTL - register
transfer level) starting from a higher level (c, c++
).
Here we will describe creating a simple algorithm (“plus 7”) in c++
using vivado_hls and then including that IP-core within your emp-payload.
Prerequisistes¶
Make sure you have installed the pre-requisites (Prerequisites) and are familiar with the first two walkthroughs linked above.
In addition you should have the vivado_hls component installed (this is an extension of standard vivado, initiated with vivado_hls
from the command-line)
and be familiar with the vivado GUI. IPBB (more info) will be used
to create the project and lastly the address table, however, vivado and vivado_hls will be used interactively to compile the HLS core, instantiate it, and then
synthesize and generate the bitfile.
Create the HLS IP Core¶
Step 1: Open the Project¶
open vivado HLS:
vivado_hls
create new project
in the file menu (or quick start icon) and choose a suitable name (e.g. walkthrough_plus7)add files
X.cc and X.h files to the project if they already exist, otherwise clicknew file
for both .cc and .h with suitable names (e.g.func.cc
andfunc.h
). NB: The .cc file extension is important for c++ even though the dialogue states “C-based source files”click
next
through theadd/remove C-based testbench files (design test)
optionsIn the Create Vivado HLS solution for selected technology choose a name (e.g. solution1) and then add the correct part for the FGPA - in the case of the KU15P this should be the
kintexuplus
family and thenxcku15p-ffva1760-2-e
(slightly different abbreviated names than in standard vivado). After choosing the right FPGA part clickFinish
.
Step 2: Create the HLS algorithm code:¶
Open the
Source
tab in the explorer (left panel) and double-click on your emptyfunc.cc
(or appropriate name chosen in 3 above).Create the content of your
func.cc
(note that .cc is important to pick upc++
compiler and not the defaultc
one):/* HLS code: */ #include "func.h" ap_int<64> myfunc(const ap_int<64> a) { ap_int<64> sum = 0; sum = a+7; return sum; }
Here we are creating a simple arithmetic operation of adding 7.
Save the file - either choose
save
in the menu orctrl-s
.Similarly create content in your header file by double-clicking on the
func.h
(must be the same name as in thec++
include statement above):/* HLS .h */ #ifndef my_func_h #define my_func_h #include <ap_int.h> #define NDATA 12 ap_int<64> myfunc(const ap_int<64> a) ; #endif
Again save the file - either
save
in the menu orctrl-s
.Set your function as the top one in the project:
Project └── project settings └── synthesis └── browse for top function └── myfunc(func.cc)
myfunc(func.cc)
should be picked up as a target or whatever you chose as the function and file name.run
c-synthesis
: either green right arrow icon or:menu └── solution └── run c-synthesis └── active solution
export
RTL as IP
: either press two buttons to the right of the green arrow icon or:menu └── solution └── export RTL
you now should have a zip file with the IP located in solution1/impl/ip. This can then be imported in your EMP vivado project in the following steps.
Step 2: Create the HLS algorithm framework:¶
Now create your own algo repo as in Walkthrough1: creating your own repository from scratch (and the Prerequisites).
If you look in the payload src directory you should find the emp_payload
:
cd src/my-algo-repo/an-algo/firmware/hdl/
ls -la
The emp_payload.vhd
is a special filename where you should create your algorithm
to be included in the EMP project. Currently our emp_payload
is a null algorithm
which copies the input buffers to the outputs. Here we would like to modify the
VHDL so that we can include our HLS as a component such that the buffers are passed through
the previously created IP-core. First you should copy your emp_payload.vhd
to a back-up filename (easier for debugging):
cp emp_payload.vhd emp_payload_nullalgo.vhd
Then you should edit emp_payload.vhd so that you have the myfunc
component and the buffers are passed through it.
This can be an exercise or if you want to directly jump to the solution
it can be downloaded - solution
along with the equivalent null algorithm.
Copying emp_payload_hls.vhd
to emp_payload.vhd
will instantiate the HLS component.
Create the full vivado project with ipbb:
cd proj/my_hls_algo
ipbb vivado generate-project
Here my_hls_algo
is your choice of algo name which you then create above. Pay attention to any warning message which IPBB outputs and correct accordingly.
Step 3: Open the EMP Project in Vivado GUI and include the HLS IP-core:¶
Open your project in vivado:
vivado sm1_hls_algo/sm1_hls_algo.xpr
Add your HLS IP directory/repoistory to the vivado project:
tools └── settings └── IP (click expand tab/arrow) └── Repository └── "plus" sign and then choose the directory that contains the zip file you created with vivado_hls (above).
Open
IP Catalog
: double click icon on left panel of GUIYou should now see your
User IP catalog
(expand tab/arrow) and with yourmyfunc
IP core (expand tab/arrow). Double click it to load it into your to the project:User Repository └── VIVADO HLS IP └── Myfunc (double click here)
Synthesize the IP core within your project (i.e. click
OK
thenGenerate
)Now (finally) create the bitfile which contains your HLS algo
Create the address Table:¶
Create address table:
ipbb vivado addrtab -d my_hls_addrtab
Download hls_connections.xml and edit it correctly according to create address table
Now you can probe the buffers and verify if your algorithm does indeed add 7 to the input buffers on the baseboard (as described in Walkthrough2: First payload modifications and buffer manipulation - “Plus5”):
empbutler -c my_connections.xml do x1 reset
Now we inject empty data to the buffers using empbutler
and capture the output:
empbutler -c my_connections.xml do x1 buffers rx PlayOnce --inject generate://empty
empbutler -c my_connections.xml do x1 buffers tx Capture
empbutler -c my_connections.xml do x1 capture
Now you can check if you have indeed been successful in your algorithm implementation, firmware build, buffer injection and capture:
geany data/rx_summary.txt
Note that tx
corresponds to the outputs (post algo) and rx
to the inputs since the reference is to the FPGA.