# HLS Lab1
[Product page](https://www.tul.com.tw/ProductsPYNQ-Z2.html)
[Read the Docs](https://pynq.readthedocs.io/en/latest/getting_started/pynq_z2_setup.html)
```mermaid
gantt
title Task Flow
axisFormat %%
section Client
install Xpra : c1, 2020-03-13, 5m
attach Vitis installer with Xpra and install Vitis : c2, after s5 c1, 90m
section Server
start Vitis installer with Xpra : s5, after s1 s2, 1m
download Vitis installer : s2, 2020-03-13, 2m
install Xpra : s1, 2020-03-13, 5m
configure Linux bridge, firewall, routing table : 2020-03-13, 5m
download ISO : s3, 2020-03-13, 15m
burn ISO : s4, after s3, 15m
section Board
connect and turn on : b1, after s4, 1m
configure gateway, DNS : b2, after b1, 2m
```
## PYNQ-Z2 Setup
The board can boot from a MicroSD card.
[Appendix](https://pynq.readthedocs.io/en/latest/appendix.html#linux)
[List of supported boards](http://www.pynq.io/board.html)
1. Download the [v2.6 boot image](http://bit.ly/pynqz2_v2_6) and unzip it; this should yield `pynq_z2_v2.6.0.img`.
2. Insert the MicroSD card and locate the device with `lsblk`, e.g., `sdb`, or
```
udevadm monitor -k -p --subsystem-match=block | grep DEVNAME
```
3. Use `df` to check that partitions of the card, e.g., `/dev/sdb1`, are not mounted, as some systems auto-mount newly-detected partitions; if not, unmount them, e.g., `umount /dev/sdb1`.
4. Write the image to the card (not just some partition of it):
```
dd bs=4M if=pynq_z2_v2.6.0.img of=/dev/sdb status=progress
```
If a block size of 4M doesn't work, try 1M.
5. Before you remove the card, run `sync` a few times to make sure that all effects of `dd` are resolved.
## Board Networking with Linux Bridge
After boot, the board advertises itself as `192.168.2.99` if no DHCP server responds to the board.
1. Run `ip link` to see what interfaces are active:
```
enp1s0f0: <NO-CARRIER,BROADCAST,MULTICAST,UP>
enp1s0f1: <NO-CARRIER,BROADCAST,MULTICAST,UP>
enp1s0f2: <NO-CARRIER,BROADCAST,MULTICAST,UP>
enp1s0f3: <BROADCAST,MULTICAST,UP,LOWER_UP>
```
Initially, the interface `enp1s0f3` is connected to the Internet whereas the others are not connected to anything.
2. Connect the board (with the power on) to the server, and run `ip link` again:
```
enp1s0f0: <NO-CARRIER,BROADCAST,MULTICAST,UP>
enp1s0f1: <NO-CARRIER,BROADCAST,MULTICAST,UP>
enp1s0f2: <BROADCAST,MULTICAST,UP,LOWER_UP>
enp1s0f3: <BROADCAST,MULTICAST,UP,LOWER_UP>
```
One can see that the cable is connected to `enp1s0f2`.
**Another way** to do this:
```
ip monitor
```
3. Create a Linux bridge `br-pynq` enslaving the interface `enp1s0f2` connected to the board:
```
nmcli c add ifname br-pynq type bridge con-name br-pynq
nmcli c add type bridge-slave ifname enp1s0f2 master br-pynq
```
4. Assign the bridge an IP address and activate it:
```
nmcli c modify br-pynq ipv4.addresses '192.168.2.1/24'
nmcli c up br-pynq
```
The address `192.168.2.1` is chosen to be in the same subnet (with mask length 24) as `192.168.2.99`.
Now one should be able to reach the board -- `192.168.2.99` -- from the server and to reach the server -- `192.168.2.1` -- from the board.
5. Set gateway -- `192.168.2.1` -- and DNS -- `8.8.8.8` and `4.4.4.4` -- for board:
```
printf "gateway 192.168.2.1\ndns-nameservers 8.8.8.8 8.8.4.4\n" >> /etc/network/interfaces.d/eth0
dpkg-reconfigure resolvconf
ifdown "eth0:1" && ifup "eth0:1"
```
If fortunate, `ping google.com` would work; if not, the firewall rules of the server should be set accordingly to allow traffic between the Internet-facing interface `enp1s0f3` and the bridge `br-pynq`:
```
sysctl -w net.ipv4.ip_forward=1
firewall-cmd --zone=FedoraServer --add-masquerade
firewall-cmd --runtime-to-permanent
```
## Remote Access to the Board and Vivado
Two choices are available:
- Port forwarding and X windows forwarding via **SSH**.
- Direct access to the subnet `192.168.2.0/24` and high performance remote X windows connection via **VPN**.
### SSH
### Wireguard VPN
## Installing Vivado and Vitis
[Download page](https://www.xilinx.com/support/download.html)
[Release Notes](https://www.xilinx.com/support/documentation/sw_manuals/xilinx2020_2/ug973-vivado-release-notes-install-license.pdf)
This example uses [Xilinx Unified Installer 2020.2: Linux Self Extracting Web Installer](https://www.xilinx.com/member/forms/download/xef.html?filename=Xilinx_Unified_2020.2_1118_1232_Lin64.bin)
1. Install X11 without a desktop environment:
```
#dnf install xorg-x11* # not necessary, read next section
```
2. Start vivado:
```
source /home/xilinx/xilinx/Vivado/2020.2/settings64.sh
vivado
```
Since Fedora is not on the offical support list of operating systems, I had to deal with the following missing shared objects.
- `libtinfo.so.5`
According to [this](https://forums.xilinx.com/t5/Design-Entry/librdi-commontasks-so-and-libtinfo-so-5-are-not-being-loaded/td-p/1055657), one can simply use the existing `libtinfo.so.6` in place of the expected `libtinfo.so.5`:
```
ln -s /usr/lib64/libtinfo.so.6 /usr/lib64/libtinfo.so.5
```
- `libcrypt.so.1`
According to [this](https://tex.stackexchange.com/questions/493231/biber-missing-libcrypt-so-1-library-on-fedora?answertab=votes#tab-top), Fedora replaced `libcrypt` with a safer library based on `libxcrypt`, yet a compatibility package exists:
```
dnf install libxcrypt-compat
```
The application also took plenty of seconds to launch, but this seems like standard behavior.
## Remote X
1. Install xpra on the server.
This will also pull all the X11 dependencies.
```
#dnf --setopt=install_weak_deps=False --best install xpra
```
[USE THIS](https://github.com/Xpra-org/xpra/wiki/Download)
2. Connect:
```
xpra start ssh://hound/ \
--start-child=vivado \
--exit-with-children \
--pulseaudio=no \
--file-transfer=off \
--speaker=disabled \
--microphone=disabled \
--bell=no \
--printing=no \
--html=off \
--exit-ssh=yes \
--webcam=no
# --chdir ~/.vivado
```
Issue:
```
Error: cannot enable SSH socket upgrades:
No module named 'paramiko'
```
Soluion:
```
pip3 install paramiko
```
[A useful link](https://nyllep.wordpress.com/2020/09/02/xpra-gui-%E7%95%8C%E7%9A%84-screen-tmux/)
[How to detach](https://unix.stackexchange.com/questions/477352/how-to-detach-from-xpra-started-from-client)
## Vitis HLS and Vivado
[Extensive documentation](https://www.xilinx.com/html_docs/xilinx2020_2/vitis_doc/gnq1597858079367.html)
[Cern slides](https://indico.cern.ch/event/857790/attachments/1929374/3199760/HLS_Tutorial.pdf)
[Vitis HLS guide](https://www.xilinx.com/support/documentation/sw_manuals/xilinx2020_2/ug1399-vitis-hls.pdf)
[Using Vivado HLS](http://bertrand.granado.free.fr/FPGA2/FPGA_2/FPGA2_-_Documentation_files/12_Using_VivadoHLS.pdf)
[PYNQ Overlay](https://pynq.readthedocs.io/en/v2.4/pynq_overlays.html)
[Questions about the use case of Overlay in PYNQ](https://discuss.pynq.io/t/question-about-the-use-case-of-overlay-in-pynq/252/2)
## How High-level is High-level
```
low-level high-level
<----------+---+-------->
| Assembly | C | Python |
+----------+---+--------+
| C++ |
+------------+
```
OpenCL is a C library which by modern standard is rather low-level.
Its Python binding remains loyal to the C-style API, which doesn't make it any easier to program.
Fortunately, Khronos maintains a modern C++ library -- [SYCL](https://www.khronos.org/sycl/) -- built on top of OpenCL; SYCL is by all means high-level.
[triSYCL](https://github.com/triSYCL/triSYCL) is an incomplete reference implementation of the SYCL standard.
- [Look ma, no CUDA! Programming GPUs with modern C++ and SYCL](https://nazavode.github.io/blog/sycl/)
- [Status of triSYCL implementation, 2017](https://www.khronos.org/assets/uploads/developers/library/2017-supercomputing/Xilinx-triSYCL-complete_Nov17.pdf)
- [Khronos Group SYCL standard - triSYCL Open Source Implementation, 2016](https://www.khronos.org/assets/uploads/developers/library/2016-supercomputing/triSYCL-Open-Source-Implementation_Nov16.pdf)
- [SYCL -- A Single-Source C++ Standard for Heterogeneous Computing](https://www.khronos.org/assets/uploads/developers/library/2019-supercomputing/SC19-H2RC-keynote-SYCL_Nov19.pdf)