Skip to content

Lift to Vitis HLS 2020.2 and PYNQ 2.7 #2

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 14 commits into
base: master
Choose a base branch
from
5 changes: 5 additions & 0 deletions .clang-format
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
Language: Cpp
BasedOnStyle: WebKit
...

3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
**/accel
**/vitis_hls.log
zynq/build
294 changes: 155 additions & 139 deletions README.md

Large diffs are not rendered by default.

Binary file added image/install-01-product.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added image/install-02-edition.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added image/install-03-component.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion zynq/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ BUILD_DIR = build
SCRIPT_DIR = tcl

# Executables
VIVADO_HLS = vivado_hls
VIVADO_HLS = vitis_hls
VIVADO = vivado

.PHONY: all setup ip bit clean
Expand Down
10 changes: 7 additions & 3 deletions zynq/hls/mmult_fixed/hls.tcl
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,16 @@
set src_dir "."
open_project accel
set_top mmult_hw
add_files $src_dir/mmult_fixed.cpp
add_files $src_dir/mmult_float.cpp
add_files -tb $src_dir/mmult_test.cpp
open_solution "solution0"

open_solution "solution0" -flow_target vivado
set_part {xc7z020clg484-1}
create_clock -period 10 -name default
set_clock_uncertainty 12.5%

config_compile -pipeline_loops 0
csim_design -clean
csynth_design
close_project
exit
exit
29 changes: 15 additions & 14 deletions zynq/hls/mmult_fixed/mmult.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@

#include <assert.h>
#include <ap_axi_sdata.h>
#include <assert.h>
#include <hls_stream.h>

// Type definition of matrix elements
typedef ap_int<8> w_T;
Expand All @@ -15,14 +16,14 @@ typedef unsigned out_bit_T;
typedef unsigned long long axi_T;

// Datatype widths in bits
#define W_WIDTH (sizeof(w_T)*8)
#define IN_WIDTH (sizeof(in_T)*8)
#define OUT_WIDTH (sizeof(out_T)*8)
#define W_WIDTH (sizeof(w_T) * 8)
#define IN_WIDTH (sizeof(in_T) * 8)
#define OUT_WIDTH (sizeof(out_T) * 8)

// Data type ratio between data type and axi width
#define W_WIDTH_RATIO (8*sizeof(axi_T)/W_WIDTH)
#define IN_WIDTH_RATIO (8*sizeof(axi_T)/IN_WIDTH)
#define OUT_WIDTH_RATIO (8*sizeof(axi_T)/OUT_WIDTH)
#define W_WIDTH_RATIO (8 * sizeof(axi_T) / W_WIDTH)
#define IN_WIDTH_RATIO (8 * sizeof(axi_T) / IN_WIDTH)
#define OUT_WIDTH_RATIO (8 * sizeof(axi_T) / OUT_WIDTH)

// Matrix dimensions specifications
#define BATCH 8192
Expand All @@ -34,21 +35,21 @@ typedef unsigned long long axi_T;
// #define TILING

// Input/Output Stream Size
#define IS_SIZE ((CLASSES+OUT_WIDTH_RATIO-1)/OUT_WIDTH_RATIO+CLASSES*FEAT/W_WIDTH_RATIO+BATCH*FEAT/IN_WIDTH_RATIO)
#define OS_SIZE (BATCH*((CLASSES+OUT_WIDTH_RATIO-1)/OUT_WIDTH_RATIO))
#define IS_SIZE ((CLASSES + OUT_WIDTH_RATIO - 1) / OUT_WIDTH_RATIO + CLASSES * FEAT / W_WIDTH_RATIO + BATCH * FEAT / IN_WIDTH_RATIO)
#define OS_SIZE (BATCH * ((CLASSES + OUT_WIDTH_RATIO - 1) / OUT_WIDTH_RATIO))

// AXI settings (leave it fixed)
#define AXI_DATA (sizeof(axi_T)*8)
#define AXI_DATA (sizeof(axi_T) * 8)
#define AXI_U 4
#define AXI_TI 5
#define AXI_TD 5

// AXI interface
typedef ap_axiu<AXI_DATA,AXI_U,AXI_TI,AXI_TD> AXI_VAL;
typedef ap_axiu<AXI_DATA, AXI_U, AXI_TI, AXI_TD> AXI_VAL;

// Matrix Multiply prototype
void mmult_hw (AXI_VAL in_stream[IS_SIZE],AXI_VAL out_stream[OS_SIZE]);
void mmult_hw(hls::stream<AXI_VAL>& in_stream, hls::stream<AXI_VAL>& out_stream);

// AXI stream push and pop
axi_T pop_stream(AXI_VAL const &e);
AXI_VAL push_stream(axi_T const &v, bool last);
axi_T pop_stream(hls::stream<AXI_VAL>& in_stream);
AXI_VAL push_stream(axi_T const& v, bool last);
143 changes: 76 additions & 67 deletions zynq/hls/mmult_fixed/mmult_fixed.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,92 +5,101 @@

// --------------------------------------------------------------------
// function to be accelerated in HW wrapped with AXI4-Stream interface
void mmult_hw (AXI_VAL in_stream[IS_SIZE], AXI_VAL out_stream[OS_SIZE])
void mmult_hw(hls::stream<AXI_VAL>& in_stream, hls::stream<AXI_VAL>& out_stream)
{
#pragma HLS INTERFACE s_axilite port=return bundle=CONTROL_BUS
#pragma HLS INTERFACE axis port=in_stream
#pragma HLS INTERFACE axis port=out_stream

// Assertions (to avoid out of array bound writes)
assert(BATCH%TILING==0);
assert(FEAT%W_WIDTH_RATIO==0);
assert(FEAT%IN_WIDTH_RATIO==0);
assert((BATCH*CLASSES)%OUT_WIDTH_RATIO==0);

// Hardware memory buffers
out_T offset_buf[CLASSES];
w_T weight_buf[CLASSES][FEAT];
in_T in_buf[TILING][FEAT];
out_T out_buf[TILING][CLASSES];

// Input and output AXI stream indices
int is_idx = 0;
int os_idx = 0;

// Stream in offset vector
// CSE548 TODO

// Stream in weight matrix
// CSE548 TODO

// Iterate over tiles
LT: for (int t = 0; t < BATCH; t+=TILING) {

// Stream in input tile
// CSE548 TODO

// Perform matrix multiplication
L1: for (int i = 0; i < TILING; i++) {
// Iterate over output classes
L2: for (int j = 0; j < CLASSES; j++) {
// Perform the dot product
out_T tmp = offset_buf[j];
L3: for(int k = 0; k < FEAT; k++) {
out_T mult = in_buf[i][k] * weight_buf[j][k];
tmp += mult;
}
out_buf[i][j] = tmp;
}
}

// Stream out output matrix
// CSE548 TODO
}
// Assertions (to avoid out of array bound writes)
assert(BATCH % TILING == 0);
assert(FEAT % W_WIDTH_RATIO == 0);
assert(FEAT % IN_WIDTH_RATIO == 0);
assert((BATCH * CLASSES) % OUT_WIDTH_RATIO == 0);

// Hardware memory buffers
out_T offset_buf[CLASSES];
w_T weight_buf[CLASSES][FEAT];
in_T in_buf[TILING][FEAT];
out_T out_buf[TILING][CLASSES];

#pragma HLS BIND_STORAGE variable=offset_buf type=RAM_T2P
#pragma HLS BIND_STORAGE variable=weight_buf type=RAM_T2P
#pragma HLS BIND_STORAGE variable=in_buf type=RAM_T2P
#pragma HLS BIND_STORAGE variable=out_buf type=RAM_T2P

// Input and output AXI stream indices
int is_idx = 0;
int os_idx = 0;

// Stream in offset vector
// CSE548 TODO

// Stream in weight matrix
// CSE548 TODO

// Iterate over tiles
LT:
for (int t = 0; t < BATCH; t += TILING) {

// Stream in input tile
// CSE548 TODO

// Perform matrix multiplication
L1:
for (int i = 0; i < TILING; i++) {
// Iterate over output classes
L2:
for (int j = 0; j < CLASSES; j++) {
// Perform the dot product
out_T tmp = offset_buf[j];
L3:
for (int k = 0; k < FEAT; k++) {
out_T mult = in_buf[i][k] * weight_buf[j][k];
tmp += mult;
}
out_buf[i][j] = tmp;
}
}

// Stream out output matrix
// CSE548 TODO
}
}


// --------------------------------------------------------
// functions to insert and extract elements from an axi stream
// includes conversion to correct data type
axi_T pop_stream(AXI_VAL const &e)
axi_T pop_stream(hls::stream<AXI_VAL>& in_stream)
{
#pragma HLS INLINE
AXI_VAL e;
in_stream.read(e);

axi_T ret = e.data;
axi_T ret = e.data;

volatile ap_uint<sizeof(axi_T)> strb = e.strb;
volatile ap_uint<sizeof(axi_T)> keep = e.keep;
volatile ap_uint<AXI_U> user = e.user;
volatile ap_uint<1> last = e.last;
volatile ap_uint<AXI_TI> id = e.id;
volatile ap_uint<AXI_TD> dest = e.dest;
volatile ap_uint<sizeof(axi_T)> strb = e.strb;
volatile ap_uint<sizeof(axi_T)> keep = e.keep;
volatile ap_uint<AXI_U> user = e.user;
volatile ap_uint<1> last = e.last;
volatile ap_uint<AXI_TI> id = e.id;
volatile ap_uint<AXI_TD> dest = e.dest;

return ret;
return ret;
}

AXI_VAL push_stream(axi_T const &v, bool last = false)
AXI_VAL push_stream(axi_T const& v, bool last = false)
{
#pragma HLS INLINE

AXI_VAL e;
AXI_VAL e;

e.data = v;
e.strb = (1<<sizeof(axi_T))-1;
e.keep = (1<<sizeof(axi_T))-1;
e.user = 0;
e.last = last ? 1 : 0;
e.id = 0;
e.dest = 0;
return e;
e.data = v;
e.strb = (1 << sizeof(axi_T)) - 1;
e.keep = (1 << sizeof(axi_T)) - 1;
e.user = 0;
e.last = last ? 1 : 0;
e.id = 0;
e.dest = 0;
return e;
}

Loading