Added sections about FIR filter implementation and testing
|}
This Technical Note shows hot to run PYNQ on Bora platform. It is worth remembering that, even though the procedure was tested on Bora, it should work on BoraX as well without any modification.
To see PYN PYNQ in action, please see [https://www.youtube.com/watch?v=LoLCtSzj9BU this clip].
==Testbed's hardware Hardware and software configurationSoftware Configuration==
As stated before, the procedure was tested on Bora/BoraEVB hardware platform.
With regard to the software configuration, the following versions were used:
*[[BELK/BXELK_software_components#Kits.27_composition|U-Boot 20142018.07 released with 1 (at the time of this writing, '''this version was not officially supported by any BELK 2.1.0]]release yet''')*Linux kernel 4.14.0 (at the time of this writing, '''this version was not officially supported by any BELK release yet''')*root file systemRoot filesystem: extracted from [http://files.digilent.com/Products/PYNQ/pynq_z1_v2.1.img3.zip Pynq-Z1 v2.1 3 image] and mounted over NFSfrom microSD card.
Original root file system included several kernel drivers built as modules. The Linux kernel used for this test was different than the kernel released along with the PYNQ's root file system, however. Consequently, these modules were not compatible with the kernel running on Bora. To overcome this issue, these drivers were linked statically into the kernel image.
==Setting up Up the boardBoard==U-Boot environment was configured in order to retrieve the kernel image and the device tree blob via TFTP protocolfrom the microSD card. Also, it was configured to make the kernel to mount the root file system over NFSfrom a partition of the microSD card.
The following box shows the full boot process (clock on the "Expand" box):
*First, a software implementation of an FIR filter was created
*A hardware implementation of the same FIR filter was generated using the [https://www.xilinx.com/products/intellectual-property/fir_compiler.html FIR Compiler] provided by Vivado.
*The resulting IP was instantiated in Programmable Logic (PL).
*Using Jupyter Notebooks, a simple Python test code was edited and run to exercise the filter.
**Two different approaches were used: generic driver and IP-specific driver.
This example was inspired by [http://www.fpgadeveloper.com/2018/03/how-to-accelerate-a-python-function-with-pynq.html this tutorial].
===Basic Operations===
*In order to open the Jupyter Notebook web dashboard, do the following steps:
**Open the browser (only Google Chrome is supported)
**Go to http://<IP address>:9090 if your board is connected to a computer via static IP address or to <nowiki>http://pynq:9090</nowiki> if your host can resolve the target's hostname
**Log in with username <code>xilinx</code> and password <code>xilinx</code>.
[[File:PYNQ-jupyter-welcome.png|thumb|center|600px|Jupyter Notebook web dashboard]]
*To move files to/from Jupyter Notebook it is convenient to share the home directory of the target's <code>xilinx</code> user. For instance, to access the Pynq home area as a network drive via Samba protocol:
*Open a file browser and click "Go" > "Enter Location"
*Log as <code>xilinx</code> with password <code>xilinx</code>.
===Editing and executing Python functions===
Before implementing the FIR filter in PL, we created a software implementation with the [https://www.scipy.org/ SciPy] library. To verify it, we applied it to a noisy signal.
In essence we
* created a new notebook by clicking on the ''New'' button at the top and select ''Python 3''
[[File:PYNQ-jupyter-new-file.png|thumb|center|600px|Creating a new notebook]]
*selected ''Code'' on the top bar and write some Python code
* clicked ''Run'' on the top bar to run code on a kernel.
The following image shows the noisy and the filtered signals.
[[File:PYNQ-jupyter-FIR-result.png|thumb|center|600px|Input and output signals]]
For more details, please refer to the section [http://www.fpgadeveloper.com/2018/03/how-to-accelerate-a-python-function-with-pynq.html ''Software FIR filter using SciPy''].
===Implementing a Hardware-Accelerated Version of the FIR Filter in PL===
To access an hardware-accelerated function from Python, PYNQ requires to load a custom overlay. Overlays are built with Vivado and are composed by:
*an FPGA bitstream (.bit file)
*a block design (.tcl file)
====Creating and Running a New Custom Overlay: Approach #1====
We created a custom overlay associated with the hardware implementation of the FIR filter. This first approach made use of the FIR Compiler tool provided by Vivado.
The fundamental steps required to do this are:
*Opening a new Vivado project, selecting ''RTL project'' and ''Bora SOM'' as the target board
*Creating your block design
**Adding ''FIR compiler'' block (included in Vivado default IP) and setting it up
**Adding ''AXI direct memory access'' block and setting it up
**On ''ZYNQ7 Processing System'' block, enabling a ''High-Performance AXI 32b/64b Slave Ports'' on interface HP0
**Connecting AXIS_DATA bus of AXI and FIR block
**''Runnin Connection Automation'' to complete wiring
*Creating Hierarchy of AXI and FIR block named <code>filter</code>
=====Running Custom Overlays with Generic Driver =====
To access the overlay with the generic driver:
*Load <code>Overlay</code> and <code>Xlnx</code> modules from <code>pynq</code> and <code>pynq.lib.dma</code>.
*Create <code>Overlay</code> and <code>Xlnk</code> objects
These steps allows you to communicate directly through a DMA buffer.
For more details, please refer to the section [http://www.fpgadeveloper.com/2018/03/how-to-accelerate-a-python-function-with-pynq.html ''Hardware FIR Implementation''].
=====Running Custom Overlays with IP-Specific Driver =====
To access the overlay with a specific driver:
*Import <code>DefaultHierarchy</code> from <code>pynq</code>
*create a new class for FIR filter with a method to communicate directly thorough a DMA buffer
*create a <code>checkhierarchy</code> method to check the IP contained under ''filter'' hierarchy
For more details, please refer to the section [http://www.fpgadeveloper.com/2018/03/how-to-accelerate-a-python-function-with-pynq.html ''Driver for FIR accelerator''].
====Creating and Running a New Custom Overlay: Approach #2====
This approach makes use of a different method to implement the filter. In this case, the filter was written in C++ and implemented by using [https://www.xilinx.com/products/design-tools/vivado/integration/esl-design.html Vivado High-Level Synthesis (HLS)].
The fundamental steps required to do this are:
*Opening a new Vivado HLS project, selecting Bora SOM as the target board
*Creating a new C++ source file
*Writing C++ code of FIR custom IP
**Creating AXI Stream interfaces for input and output
**Defining FIR coefficients and normalizing their values
**Using some #pragmas to optimize the execution of the algorithm
*Synthesizing new IP running ''Run C synthesis''
*Exporting new IP running ''Export RTL''
*Opening a new Vivado project, selecting RTL project and Bora SOM as the target board
*Adding the new IP in IP list
**Opening ''IP Catalog''
**Adding repository of the custom IP
To complete the procedure and export the Vivado project, the same steps described previously have to be done.
The data flows are implemented as AXI streams. The following images show the input and the output to/from the filter respectively.