Note: Running shell commands from python in Linux may not load your user profile, to avoid "command not found" errors, make sure that your Vivado directory is added to your PATH variable.
The training and optimization program outputs a .json
file, which serves as the input to this code generator. For simplicity, an average training output and its corresponding testpoints are included in example/
. To use this example:
$ python fwXbdt.py -f example/ex_config.json -t example/ex_testpoints.txt
bdt_hls_firmware/
. This can be examined further by opening it in Vivado HLS.Here's the example's output to your command window:
$ python3 fwXbdt.py -f example/ex_config.json -t example/ex_testpoints.txt
INFO: Removing old project
INFO: Parsing JSON configuration file.
INFO: writing preamble of bdt.hpp header file and including required libraries.
INFO: Writing constants to the bdt header file.
INFO: Defining score matrices for each tree in the desired set
INFO: Writing function prototypes to the header file.
INFO: Finalizing bdt header file.
INFO: Writing preamble to bdt.cpp implementation file.
INFO: Writing top level C++ function
INFO: Writing gridding function.
INFO: Generating testbench header file
INFO: Generating test file to be used for verification with testbench
WARNING: the test file does not have the default number of inputs. This can be ignored if a custom test file was used.
INFO: Writing testbench implementation file.
INFO: Beginning Vivado HLS C Synthesis (this may take a while)
+----------------+-------------+-------------+
| estimated (ns) | target (ns) | uncertainty |
+----------------+-------------+-------------+
| 2.712 | 3.12 | 0.39 |
+----------------+-------------+-------------+
+-------------+-------------+-------------+----+--------------+--------------+
| min latency | avg latency | max latency | II | min interval | max interval |
+-------------+-------------+-------------+----+--------------+--------------+
| 3 | 3 | 3 | 1 | 1 | 1 |
+-------------+-------------+-------------+----+--------------+--------------+
+----------+-----------+------+-----------------+
| resource | available | used | percentage used |
+----------+-----------+------+-----------------+
| DSP48E | 6840 | 0 | 0.0 |
| FF | 2364480 | 138 | 0.01 |
| LUT | 1182240 | 1903 | 0.16 |
| BRAM_18K | 4320 | 8 | 0.19 |
| URAM | 960 | 0 | 0.0 |
+----------+-----------+------+-----------------+
Now, let's take a deeper look at the generated products. Navigate to the output folder, found at `fwX/fwXmachina/Xfirmware/bdt_binary/bdt_hls_firmware/solution1`.
We can analyze the actual code generated by opening up the `src` folder and inspecting the main .cxx .hxx file (`bdt.cpp` and `bdt.hpp` by default). In `bdt.cpp`, we can see two functions. The first (`fwXbdt()`) is what is known as the top-level function, or the function that gives the physical interface shape for the synthesizer.
Right below it we see the heart of `fwXmachina/bdt_binary`. The `bin()` function takes an event vector and outputs its bin index vector. This example uses binary gridification. We can see the nested structure of the if-statements.
Next up is the header file. This file contains a ton of metadata, such as the precisions of the interface, number of variables, number of trees, the scores for each bin in each tree, and some other functions that help index these scores.
The next step, where we will actually program our FPGA, will use the generated VHDL outputs. You can find the VHDL files for the next step within the `syn` folder.