Skip to content

Commit d608a0e

Browse files
committed
Updated READMEs.
1 parent 6e4f2da commit d608a0e

File tree

2 files changed

+81
-61
lines changed

2 files changed

+81
-61
lines changed

README.md

Lines changed: 34 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -6,26 +6,13 @@ This project includes the HLS implementation and the approximation algorithms in
66

77
### SVD Approximation Algorithm
88

9-
The bot AI is trained in Google Colab following the notebook in `ai/` folder.
10-
11-
### Hardware
12-
13-
The hardware part was implemented in Vivado High Level Synthesis (HLS) C++. It exploits Xilinx OpenCV libraries for resizing and stream the video frames generated by the game.
14-
15-
#### Pong Game Cosimulation
16-
17-
#### OpenCV Cosimulation
18-
19-
#### HDMI Modules
20-
21-
For instantiating the HDMI IPs, please follow this [guide](https://forums.xilinx.com/t5/Design-and-Debug-Techniques-Blog/Video-Series-23-Generate-a-video-output-on-Pynq-Z2-HDMI-out/ba-p/932553).
22-
23-
#### Vivado Project
9+
The approximation algorithms are in the `python/` folder.
2410

2511
## Requirements
2612

2713
* CMake
28-
* Xilinx Vivado 2018.3
14+
* Xilinx Vivado 2018.3 (deprecated)
15+
* Xilinx Vitis 2021.1 (deprecated)
2916

3017
### CMake Simulation
3118

@@ -47,34 +34,29 @@ cmake ..
4734
make all
4835
```
4936

50-
## Notes on Using Vitis
37+
## Notes on Using Vitis HLS
5138

5239
### AXIS Interface and DMA
5340

54-
Vitis to include the TLAST side channel if and only if TKEEP and TSTRB are also included.
41+
Vitis will include the TLAST side channel if and only if TKEEP and TSTRB are also included.
5542

5643
In order to attach the port to a Xilinx DMA, the TLAST signal must be properly set HIGH at the end of the data transmission.
5744

5845
The TKEEP and TSTRB signals must be *always* set to HIGH, as indicated in the [AXIS documentation](https://developer.arm.com/documentation/ihi0051/a/Interface-Signals/Byte-qualifiers/TKEEP-and-TSTRB-combinations).
5946

47+
Note: for using external DMAs, we need the TLAST, TKEEP and TSTRB signals. In particular, TKEEP and TSTRB must be all set (i.e. all ones) in order to signal data packets.
6048

61-
### Partitioning hls::vector Arrays
49+
#### AxiStreamInterface Class
6250

63-
A standard way of partitioning an array is:
64-
```c++
65-
hls::stream<hls::vector<int, 4> > x_streams[M][N];
66-
#pragma HLS ARRAY_PARTITION variable=x_streams complete dim=0
67-
```
68-
However, since we are dealing with a `hls::vector` type, setting `dim=0` (all dimensions) will partition the array on the vector dimension too.
51+
This repository contains a wrapper class for kernel arguments of type `hls::stream` named `AxiStreamInterface`. The class is implemented following a _Policy-based_ C++ paradigm, meaning that it accepts either a `AxiStreamPort` or `AxiStreamFifo` as possible policies (in practice, a template argument).
6952

70-
In the example above, Vitis will create `M * N * 4` different streams (instead of just `M * N`). To fix it, manually specify the partitioning on the dimensions, like so:
71-
```c++
72-
hls::stream<hls::vector<int, 4> > x_streams[M][N];
73-
#pragma HLS ARRAY_PARTITION variable=x_streams complete dim=1
74-
#pragma HLS ARRAY_PARTITION variable=x_streams complete dim=2
75-
```
53+
The idea is to have a kernel argument, i.e. an HLS port, which can be either an AXIS interface with side-channels, or a bare FIFO interface connected to another kernel. In fact, Vitis HLS doesn't allow stream interfaces with side-channels within an IP. To overcome the issue, the `AxiStreamInterface` can be customized to be an IP port or a FIFO port, depending on the use of the kernel.
54+
55+
An example of this can be seen in `HlsKernelU` and in `svd::SvdKernel`, which specialize the `svd::KernelU` function template. In the first case, the `svd::KernelU` has its output stream port `xu_port` connected to one of the IP's ports (with side-channels). In the latter case instead, `svd::KernelU` is connected to `svd::KernelS`, and so its `xu_port` argument is an internal FIFO (without side-channels).
56+
57+
The `AxiStreamInterface` class in `axis_lib.h` can also be used with `hls::vector` types.
7658

77-
### Implementing AXIS Interfaces
59+
### AXIS Interfaces and `depth`
7860

7961
In order to implement AXIS interfaces, avoid using `depth` in the pragma, as follows:
8062
```c++
@@ -87,17 +69,29 @@ void HlsVectorKernelU(hls::stream<ap_axiu<kAxiBitwidth, 0, 0, 0> >& x_port,
8769
// ...
8870
}
8971
```
90-
The type `ap_axiu` must now be used to generate AXIS with side channels. Note: for using external DMAs, we need the TLAST, TKEEP and TSTRB signals. In particular, TKEEP and TSTRB must be all set (i.e. all ones) in order to signal data packets.
72+
The type `ap_axiu` must now be used to generate AXIS with side channels.
9173
92-
#### AxiStreamInterface Class
74+
## hls::vector Arrays on AXI-Lite Interfaces
9375
94-
This repository contains a wrapper class for kernel arguments of type `hls::stream` named `AxiStreamInterface`. The class is implemented following a _Policy-based_ C++ paradigm, meaning that it accepts either a `AxiStreamPort` or `AxiStreamFifo` as possible policies (in practice, a template argument).
76+
In Vitis 2021.1 it **not** allowed to have `hls::vector` type arguments mapped to AXI-Lite interfaces.
77+
Instead, use a bare arrays, *e.g.* `const int x[N]` instead of `const hls::vector<int, N> x`.
9578
96-
The idea is to have a kernel argument, i.e. an HLS port, which can be either an AXIS interface with side-channels, or a bare FIFO interface connected to another kernel. In fact, Vitis HLS doesn't allow stream interfaces with side-channels within an IP. To overcome the issue, the `AxiStreamInterface` can be customized to be an IP port or a FIFO port, depending on the use of the kernel.
9779
98-
An example of this can be seen in `HlsKernelU` and in `svd::SvdKernel`, which specialize the `svd::KernelU` function template. In the first case, the `svd::KernelU` has its output stream port `xu_port` connected to one of the IP's ports (with side-channels). In the latter case instead, `svd::KernelU` is connected to `svd::KernelS`, and so its `xu_port` argument is an internal FIFO (without side-channels).
80+
### Partitioning hls::vector Arrays
9981
100-
The `AxiStreamInterface` class in `axis_lib.h` can also be used with `hls::vector` types.
82+
A standard way of partitioning an array is:
83+
```c++
84+
hls::stream<hls::vector<int, 4> > x_streams[M][N];
85+
#pragma HLS ARRAY_PARTITION variable=x_streams complete dim=0
86+
```
87+
However, since we are dealing with a `hls::vector` type, setting `dim=0` (all dimensions) will partition the array on the vector dimension too.
88+
89+
In the example above, Vitis will create `M * N * 4` different streams (instead of just `M * N`). To fix it, manually specify the partitioning on the dimensions, like so:
90+
```c++
91+
hls::stream<hls::vector<int, 4> > x_streams[M][N];
92+
#pragma HLS ARRAY_PARTITION variable=x_streams complete dim=1
93+
#pragma HLS ARRAY_PARTITION variable=x_streams complete dim=2
94+
```
10195

10296
### HLS Vector Patch
10397

@@ -118,37 +112,16 @@ std::cout << "Number of elements in a: " << a::width << std::endl;
118112
// > Number of elements in a: 5
119113
```
120114

121-
## Notes on PYNQ Design
122-
123-
### Vivado Project
124-
125-
#### Xilinx DMA
126-
127-
The DMA should be configured in the following way:
128-
129-
* Max burst length to maximum
130-
* Register buffer width to maximum
131-
132-
#### HP Ports
133-
134-
All HP ports should be set to 64bit width (to avoid receiving data interleaved by zeroes).
135-
136-
137115
## TODOs
138116

139117
List of TODOs:
140118

119+
* Properly test the pruned versions of Kernel-U and Kernel-V.
141120
* ~Import u, s, v new kernels~
142-
* ~Import (and clean up?) u, s, v old kernels~
143-
* ~Import DMA functions~
144-
* ~Import and clean up HLS SVD-model-Bouganis~
145-
* ~Import and clean up HLS SVD-model-2LSTM~
146-
* ~Import some testbenches to try compile something~
147121

148122
## Bugs
149123

150124
List of possible bugs:
151125

152126
* Constructing data handler storage might lead to segmentation faults.
153-
* Having `R == 1` might trigger some asserts.
154-
* Having `output_size == H` in HlsKernelV might break hardware runs.
127+
* Having `num_active_inputs == 1` is breaking in hardware runs.

pynq/README.md

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# Notes on PYNQ Designs
2+
3+
## Vivado Project
4+
5+
### Xilinx DMA
6+
7+
The DMA should be configured in the following way:
8+
9+
* Max burst length to maximum
10+
* Register buffer width to maximum
11+
12+
### HP Ports
13+
14+
All HP ports should be set to their maximum size width (64bit for the PYNQ-Z1 board and 128bit for the ZCU104) in order to avoid receiving data interleaved by zeroes.
15+
16+
## Jupyter Notebook
17+
18+
### Generating Randomly-filled Buffer
19+
20+
```python
21+
import numpy as np
22+
23+
R, N, G = 64, 2, 4
24+
25+
xus = np.random.randn(R, N, G).astype(dtype=np.int16)
26+
xus_buffer = pynq.allocate(shape=(R, N, G), dtype=np.int16)
27+
np.copyto(xus_buffer, xus, casting='no')
28+
```
29+
30+
### Storing and Loading Weights from bin file
31+
32+
```python
33+
import numpy as np
34+
35+
R, N, G = 64, 2, 4
36+
37+
tmp = np.random.randn(R, N, G).astype(dtype=np.int16)
38+
tmp.tofile('binfile_example.bin')
39+
40+
def load_from_bin(binfile, shape, dtype):
41+
tmp_buffer = pynq.allocate(shape=shape, dtype=dtype)
42+
tmp = np.fromfile(binfile, dtype=data_t).reshape(tmp_buffer.shape)
43+
np.copyto(tmp_buffer, tmp, casting='no')
44+
return tmp_buffer
45+
46+
xus_buffer = load_from_bin('binfile_example.bin', shape=(R, N, G), dtype=np.int16)
47+
```

0 commit comments

Comments
 (0)