# LabB - Systolic Array
## Table of Content
:::warning
[toc]
:::
## Reference
[Xilinx Vitis_Accel_Examples : Systolic Array](https://github.com/Xilinx/Vitis_Accel_Examples/tree/2022.1/cpp_kernels/systolic_array)
## Problems encountered during the experiment & solutions
:::info
../src/host.cpp:27:10: fatal error: xcl2.hpp: No such file or directory
:::
### Solution
到以下的網址下在xcl2.cpp和xcl2.hpp,並將兩個檔案加入host的source中即可解決。
["xcl2.hpp" & "xcl.hpp" resource](https://github.com/Xilinx/SDAccel_Examples/tree/master/libs/xcl2)
:::info
The original host code checks for the `argc` parameter to be only 2, which can cause errors during the execution of the host code.

:::
### Solution
修改load binary file的argc,還有修改if的判斷條件(argc != 2 -> argc < 4)
```clike=
// print number of arguments & each argument component
std::cout << "argc = " << argc << std::endl;
for (int i = 0; i < argc; i++) {
std::cout << "argv[" << i << "] = " << argv[i] << std::endl;
}
// modify the condition
if (argc < 4) {
std::cout << "Usage: " << argv[0] << " <XCLBIN File>" << std::endl;
return EXIT_FAILURE;
}
std::string binaryFile = argv[3];
```
:::info
在原始給定的程式碼中,是這樣定義Kernel Function的I/O Port的。
```clike=
void mmult(const int* a, // Read-Only Matrix A
const int* b, // Read-Only Matrix B
int* c, // Output Result
int a_row, // Matrix A Row Size
int a_col, // Matrix A Col Size
int b_col // Matrix B Col Size
) {
```
但使用const來宣告會導致C Synthesis無法合成出對應I/O Port,會使得C/RTL Co-simulation時會有Error。
:::
### Solution
將傳輸array的argument a, b, c定義為volitile的type即可解決。
```clike=
void mmult(volatile int* a, // Read-Only Matrix A
volatile int* b, // Read-Only Matrix B
volatile int* c, // Output Result
int a_row, // Matrix A Row Size
int a_col, // Matrix A Col Size
int b_col // Matrix B Col Size
) {
// AXI4 Master's depth must be a constant and should be adjusted according to MAX_SIZE * MAX_SIZE
#pragma HLS INTERFACE m_axi port=a offset=slave bundle=gmem0 depth=256
#pragma HLS INTERFACE m_axi port=b offset=slave bundle=gmem1 depth=256
#pragma HLS INTERFACE m_axi port=c offset=slave bundle=gmem2 depth=256
#pragma HLS INTERFACE s_axilite port=a bundle=control
#pragma HLS INTERFACE s_axilite port=b bundle=control
#pragma HLS INTERFACE s_axilite port=c bundle=control
#pragma HLS INTERFACE s_axilite port=a_row bundle=control
#pragma HLS INTERFACE s_axilite port=a_col bundle=control
#pragma HLS INTERFACE s_axilite port=b_col bundle=control
#pragma HLS INTERFACE s_axilite port=return bundle=control
```
## Experiment Process
The detailed experiment process can be referenced in the following tutorial PPT.
["My tutorial PPT for Systolic Array (Broadcasting & Propagating)"](https://github.com/kevin33713371/2024_Fall_NTU_AAHLS_SP/blob/main/LabB_presentation.pdf)