|
| 1 | +# Compiling the SmartHLS + RISC-V + H264 over Ethernet Example |
| 2 | + |
| 3 | +This readme explains how to compile the different aspects of the example. It covers |
| 4 | +how to compile the HLS modules, compile the Libero project to generate a bitstream, |
| 5 | +compile the application software and update the example webpage on the board. |
| 6 | + |
| 7 | +## Requirements To Recompile the Example: |
| 8 | + |
| 9 | +- Use Libero/SmartHLS release 2023.2 |
| 10 | +- Use Linux as development environment to recompile the example using the provided |
| 11 | + scripts and commands in this file. |
| 12 | +- Use the PolarFireSoC Video Kit with Production Silicon. For boards with |
| 13 | + Engineering Sample silicon you would need to change the project parameters in |
| 14 | + the `sev-kit-reference-design/MPFS_SEV_KIT_REFERENCE_DESIGN.tcl` file. |
| 15 | + |
| 16 | +## Example Setup |
| 17 | + |
| 18 | +Before compiling the example make sure you can run the it on the board using the |
| 19 | +pre-compiled binaries, and that you can see the video streaming. This will ensure |
| 20 | +you have all the necessary connections and that you assigned an IPv4 address to |
| 21 | +the board. See [Readme.md](./Readme.md). |
| 22 | + |
| 23 | +**NOTE:** After the example is up and running, make sure to export the ``BOARD_IP`` |
| 24 | +variable with the assigned IPv4 value and connect to the right Ethernet port on |
| 25 | +the board. This will be required to copy files over to the board from your Host PC. |
| 26 | +``` |
| 27 | +export BOARD_IP=192.168.2.1 |
| 28 | +``` |
| 29 | + |
| 30 | +## Source Code Directory Structure |
| 31 | + |
| 32 | +Overall this is the directory tree of the Libero project: |
| 33 | +``` |
| 34 | +. |
| 35 | +├── MPFS_SEV_KIT_REFERENCE_DESIGN.tcl |
| 36 | +└── script_support |
| 37 | + ├── additional_configurations |
| 38 | + │ ├── functions.tcl |
| 39 | + │ └── smarthls |
| 40 | + ├── components |
| 41 | + │ ├── apb3_if.tcl |
| 42 | + │ ├── Bayer_Interpolation_C0.tcl |
| 43 | + │ ... |
| 44 | + ├── constraint |
| 45 | + │ ├── fp |
| 46 | + │ ├── io |
| 47 | + │ └── user.sdc |
| 48 | + ├── hdl |
| 49 | + │ ├── ddr_write_controller_enc.v |
| 50 | + │ ├── frame_controls_gen.v |
| 51 | + │ ├── H264 |
| 52 | + │ ├── intensity_average.vhd |
| 53 | + │ ├── ram2port.vhd |
| 54 | + │ └── video_fifo.vhd |
| 55 | + ├── hdl_source.tcl |
| 56 | + ├── hss-envm-wrapper.mpfs-sev-kit.hex |
| 57 | + └── MSS_SEV |
| 58 | + ├── ENVM.cfg |
| 59 | + └── MSS_SEV.cfg |
| 60 | +``` |
| 61 | + |
| 62 | +The `MPFS_SEV_KIT_REFERENCE_DESIGN.tcl` file drives the Libero flow, it will |
| 63 | +eventually call SmartHLS to generate the verilog modules and include them in the |
| 64 | +design. |
| 65 | + |
| 66 | +The `script_support` includes all the necessary files for the project, including |
| 67 | +all the SmartDesign components described as .tcl files, constraints, additional |
| 68 | +HDL sources and HSS firmware. |
| 69 | + |
| 70 | +The SmartHLS project files under the `smarthls` directory are described in |
| 71 | +[SmartHLS Directory Structure](#smarthls-directory-structure) section. |
| 72 | + |
| 73 | +There are a few things that can be changed in this example: |
| 74 | + |
| 75 | +1. The C++ code to generate the HLS modules in the FPGA. |
| 76 | +2. The C++ application code that control the HLS modules (runs on RISC-V CPU) |
| 77 | +3. The website: HTML and scripts to control the GUI appearance and behavior. |
| 78 | +4. The Libero project itself. |
| 79 | + |
| 80 | +## Compiling the SmartHLS Modules and Libero Project |
| 81 | + |
| 82 | +To compile the example from the command line make sure Libero and SmartHLS are |
| 83 | +in the PATH in your terminal. You can confirm this by typing the following commands: |
| 84 | + |
| 85 | +``` |
| 86 | +which shls |
| 87 | +``` |
| 88 | + |
| 89 | +``` |
| 90 | +which libero |
| 91 | +``` |
| 92 | + |
| 93 | + |
| 94 | +and compile by typing the following commands: |
| 95 | +``` |
| 96 | +cd sev-kit-reference-design |
| 97 | +./script_support/additional_configurations/smarthls/run_libero.sh |
| 98 | +``` |
| 99 | +Notice the relative path from which the script has to be executed. The compilation |
| 100 | +process may take about 40 min. depending on how fast the machine is. |
| 101 | + |
| 102 | +The `run_libero.sh` script calls Libero and passes the `MPFS_SEV_KIT_REFERENCE_DESIGN.tcl` |
| 103 | +script along with some arguments. It is this TCL file that drives the compilation flow. |
| 104 | +One of the steps in the flow is to call SmartHLS to compile the C++ code into |
| 105 | +Verilog and integrate the HLS cores into the overall Libero design. |
| 106 | + |
| 107 | +When this is done you can find the bitstream in the following location and the |
| 108 | +FPGA can be programmed using Microchip's FPExpress tool: |
| 109 | +``` |
| 110 | +./SEVPFSOC_H264/SEVPFSOC_H264.job |
| 111 | +``` |
| 112 | + |
| 113 | +**NOTEs:** |
| 114 | +- Place-and-route has been configured to run up to 16 times in case it fails to |
| 115 | + meet timing. You can also adjust the P&R seed once you find a good value after |
| 116 | + you have made some changes to the design. |
| 117 | + These settings can be found in this file: |
| 118 | + `sev-kit-reference-design/script_support/additional_configurations/smarthls/pre_hls_integration.tcl` |
| 119 | + |
| 120 | +## Compiling the C++ Application Software |
| 121 | + |
| 122 | +Before compiling and updating the software application make sure to click the |
| 123 | +`Stop` button to allow the binaries (.elf files) to be updated. |
| 124 | + |
| 125 | +There are two main executables binaries that need to be compiled. One is |
| 126 | +executed when the frames flow trough the CPU data path, and the other when the frames |
| 127 | +flow through the FPGA fabric. In the CPU data path case, only the get_frame() and |
| 128 | +put_frame() HLS functions are used to move frames to/from DDR. In the FPGA data |
| 129 | +path all the HLS functions are used. |
| 130 | + |
| 131 | +There is a script that compiles the executables for both paths, just type the |
| 132 | +following: |
| 133 | +``` |
| 134 | +cd sev-kit-reference-design/script_support/additional_configurations/smarthls/hls_pipeline |
| 135 | +./compile_all.sh |
| 136 | +``` |
| 137 | + |
| 138 | +This will compile the code and copy the .elf files over to the board using `scp`. |
| 139 | +Make sure the `BOARD_IP` environment variable has been setup as described in the |
| 140 | +[Example Setup](#example_setup) section |
| 141 | + |
| 142 | +If all goes well, then you should see the text `"ALL_DONE"` at the end. At this |
| 143 | +point you can click on the `Start` button and the updated .elf files will be used. |
| 144 | + |
| 145 | +The `compile_all.sh` script calls twice another script (`compile_and_copy.sh`) |
| 146 | +that actually has all the steps to compile the application. You can use it to |
| 147 | +only compile one path. For example, to compile only the FPGA data path type |
| 148 | +this from the command line: |
| 149 | +``` |
| 150 | +datapath=fpga arch=riscv_64 ./compile_and_copy.sh |
| 151 | +``` |
| 152 | + |
| 153 | +## Updating the On-board Website |
| 154 | + |
| 155 | +The website files are located under the |
| 156 | +`sev-kit-reference-design/script_support/additional_configurations/smarthls/www` |
| 157 | +directory and has the following structure: |
| 158 | + |
| 159 | +## Website Files |
| 160 | + |
| 161 | +The `www` directory include the files required by the web server that runs on the |
| 162 | +on-board embedded Linux, and it has the following structure: |
| 163 | + |
| 164 | +``` |
| 165 | +./www |
| 166 | +├── h264 |
| 167 | +│ ├── 0001_daemon |
| 168 | +│ ├── ffmpeg.sh |
| 169 | +│ ├── footer_h264.png |
| 170 | +│ ├── header_h264.png |
| 171 | +│ ├── index.htm |
| 172 | +│ ├── mchp_logo2.png |
| 173 | +│ ├── microchip_100x56.bmp |
| 174 | +│ ├── microchip_202x114.bmp |
| 175 | +│ ├── microchip.ico |
| 176 | +│ ├── microchip_logo.png |
| 177 | +│ ├── microchip_riscv_1280x720.bmp |
| 178 | +│ ├── pfsoc.css |
| 179 | +│ ├── reset.png |
| 180 | +│ ├── setup_vars.sh |
| 181 | +│ ├── start.php |
| 182 | +│ ├── stop.php |
| 183 | +│ ├── stop.sh |
| 184 | +│ ├── update.php |
| 185 | +│ └── update.sh |
| 186 | +└── update_website.sh |
| 187 | +``` |
| 188 | +The entry point is the `index.htm` page, which calls the rest of the scripts as |
| 189 | +needed. The web server uses a mix of Javascript and PHP code to run code on the |
| 190 | +client and server side, respectively. |
| 191 | + |
| 192 | +On the client side, the Javascript code is used to set event for clicking the |
| 193 | +"start", "update", "stop", update the Frames-per-second label on the webpage, and |
| 194 | +to call the PHP scripts. |
| 195 | + |
| 196 | +On the server side, the PHP scripts call BASH scripts to start, update and stop |
| 197 | +the FFMPEG program to transfer the frames over the network, and the SmartHLS |
| 198 | +applications that control the video pipeline modules described in C++. |
| 199 | + |
| 200 | +You can change any of these files on the host machine and then copy the updated |
| 201 | +files to the board. This can be easily done by typing the following command |
| 202 | +(make sure the `BOARD_IP` variable is defined): |
| 203 | +``` |
| 204 | +cd sev-kit-reference-design/script_support/additional_configurations/smarthls/www |
| 205 | +./update_website.sh |
| 206 | +``` |
| 207 | + |
| 208 | +## SmartHLS Directory Structure |
| 209 | + |
| 210 | +Inside the `script_support/additional_configurations/smarthls` the structure is |
| 211 | +as follows: |
| 212 | + |
| 213 | +``` |
| 214 | +smarthls |
| 215 | +├── common |
| 216 | +│ ├── bmp.hpp |
| 217 | +│ ├── sev.hpp |
| 218 | +│ ├── toronto_100x56.bmp |
| 219 | +│ └── toronto_1280x720.bmp |
| 220 | +├── compile_and_integrate_shls_to_refdesign.tcl |
| 221 | +├── hdl |
| 222 | +│ ├── async_fifo |
| 223 | +│ ├── axis-video |
| 224 | +│ └── video-axis |
| 225 | +├── hls_pipeline |
| 226 | +│ ├── app_hls_pipeline.cpu.cpp |
| 227 | +│ ├── app_hls_pipeline.fpga.cpp |
| 228 | +│ ├── compile_all.sh |
| 229 | +│ ├── compile_and_copy.sh |
| 230 | +│ ├── config.tcl |
| 231 | +│ ├── hls_pipeline.cpp |
| 232 | +│ └── Makefile |
| 233 | +├── hls.sdc |
| 234 | +├── identify_instrument.tcl |
| 235 | +├── MSS |
| 236 | +│ └── MSS_SEV.cfg |
| 237 | +├── pf_ccc_c0.mod.tcl |
| 238 | +├── pre_hls_integration.tcl |
| 239 | +├── rotozoom |
| 240 | +│ ├── config.tcl |
| 241 | +│ ├── Makefile |
| 242 | +│ ├── rotozoom.cpp |
| 243 | +│ ├── rotozoom.hpp |
| 244 | +│ └── SinCosTables.hpp |
| 245 | +├── run_libero.sh |
| 246 | +├── sd_add_aximm_mirror.tcl |
| 247 | +├── sd_add_axis_converters.tcl |
| 248 | +├── synplify_enable_dbg_mode.tcl |
| 249 | +└── www |
| 250 | + ├── h264 |
| 251 | + └── update_website.sh |
| 252 | +``` |
| 253 | + |
| 254 | +In this structure, the `hls_pipeline` directory contains the SmartHLS project. This |
| 255 | +includes the two main() software programs `app_hls_pipeline.cpu.cpp` and |
| 256 | +`app_hls_pipeline.fpga.cpp` that will be compiled to two different `.elf` files. |
| 257 | +One for each datapath: CPU and FPGA, respectively. These programs are meant to |
| 258 | +be executed by RISC-V processor. |
| 259 | + |
| 260 | +The C++ functions that will be converted into verilog are described in the |
| 261 | +`hls_pipeline.cpp` file. This file also includes another `main()` function, but |
| 262 | +this is used as a testbench for the functions when compiled on the host machine, |
| 263 | +not for the actual software that will run RISC-V processor. |
| 264 | + |
| 265 | +The rotozoom module is an example of how other functions can be defined in their |
| 266 | +own directory and have a separate testbench, and yet be able to be included into |
| 267 | +the main `hls_pipeline.cpp` file by just including the `rotozoom.hpp` header file |
| 268 | +to import the core functionality. |
| 269 | + |
| 270 | +The `pre_hls_integration.tcl` file contains TCL commands that make modifications |
| 271 | +to the original reference design in preparation for the SmartHLS module integration. |
| 272 | +This script is needed |
| 273 | + |
| 274 | +The `compile_and_integrate_shls_to_refdesign.tcl` is the script that calls SmartHLS |
| 275 | +as part of the overall Libero flow. This is know as the SmartHLS `"Custom flow"` |
| 276 | +because it uses SmartHLS as a *plug-in*. In this particular case, the script |
| 277 | +calls the SmartHLS `hw` target from the command line, which will do three things: |
| 278 | +1. Generate the Verilog code from the C++ description |
| 279 | +2. Generate the SmartDesign HDL+ components from the Verilog code and integrate |
| 280 | + them into the Libero project making the HLS modules available to the RISC-V |
| 281 | + processor. |
| 282 | +3. Generate the C++ API driver to be included in the RISC-V application software. |
| 283 | + |
| 284 | +The `Makefile` and `config.tcl` are the SmartHLS project files. If you need to |
| 285 | +define additional compilation constants for the SmartHLS project you can do so |
| 286 | +in this `Makefile`. |
| 287 | + |
| 288 | +Finally, the `common` directory has some common bitmaps and helper code. |
| 289 | + |
| 290 | +## References: |
| 291 | + |
| 292 | +[SmartHLS User Guide](https://microchiptech.github.io/fpga-hls-docs/) |
| 293 | + |
| 294 | +[PolarFire_SoC_FPGA_H264_Video_Streaming_Over_Ethernet_Application_Note_AN4529.pdf](https://ww1.microchip.com/downloads/aemDocuments/documents/FPGA/ApplicationNotes/ApplicationNotes/PolarFire_SoC_FPGA_H264_Video_Streaming_Over_Ethernet_Application_Note_AN4529.pdf) |
0 commit comments