scalehls
scalehls copied to clipboard
export IP error on atax
To move forward after HLS with logic synthesis, vivado HLS needs to export the design as a Xilinx IP. I was trying to synthesize an atax kernel from Polybench, and the export_design command fails with the following error:
missing operand at _@_
in expression " _@_* / 8"
(parsing expression " * / 8")
invoked from within
"expr $mem_width * $mem_depth / 8"
("native_bram" arm line 8)
invoked from within
"switch -nocase -- $type {
axi4lite {
# {{{
## direction
if {$mode == "master"} {
set dir0 ..."
("foreach" body line 5)
invoked from within
"foreach interface_name [dict keys $Interfaces] {
set interface_detail [dict get $Interfaces $interface_name]
set ctype ""
dict with interf..."
(file "run_ippack.tcl" line 1163)
INFO: [Common 17-206] Exiting Vivado at Mon Apr 11 14:12:06 2022...
ERROR: [IMPL 213-28] Failed to generate IP.
Since the error talks about axilite, I tried changing the pragmas in the _dse.cpp file generated by scaleHLS, and discovered that the synthesis works fine if I remove #pragma HLS resource variable=v3 core=ram_s2p_bram
from one of the input arguments. So, I am not entirely sure whether this is a Vivado problem or a scaleHLS problem, but I thought it makes sense to report it, as it may be caused by the pragma settings.
This is the smallest example if someone wants to reproduce the issue. Input code:
# define M 2
# define N 2
void test_atax(float A[2][2], float x[2], float y[2], float tmp[2])
{
int i, j;
for (i = 0; i < N; i++)
y[i] = 0;
for (i = 0; i < M; i++)
{
tmp[i] = 0.0;
for (j = 0; j < N; j++)
tmp[i] = tmp[i] + A[i][j] * x[j];
for (j = 0; j < N; j++)
y[j] = y[j] + A[i][j] * tmp[i];
}
}
Code optimized by scaleHLS (to see which input pragma I am talking about):
//===------------------------------------------------------------*- C++ -*-===//
//
// Automatically generated file for High-level Synthesis (HLS).
//
//===----------------------------------------------------------------------===//
#include <algorithm>
#include <ap_axi_sdata.h>
#include <ap_fixed.h>
#include <ap_int.h>
#include <hls_math.h>
#include <hls_stream.h>
#include <math.h>
#include <stdint.h>
#include <string.h>
using namespace std;
/// This is top function.
/// Latency=42, interval=42
/// DSP=5, BRAM=0
void test_atax(
float v0[2][2],
float v1[2],
float v2[2],
float v3[2]
) { // L5, [0,42)
#pragma HLS interface s_axilite port=return bundle=ctrl
#pragma HLS interface bram port=v0
#pragma HLS interface bram port=v3
#pragma HLS array_partition variable=v0 cyclic factor=2 dim=2
#pragma HLS resource variable=v0 core=ram_s2p_bram
#pragma HLS array_partition variable=v1 cyclic factor=2 dim=1
#pragma HLS array_partition variable=v2 cyclic factor=2 dim=1
#pragma HLS resource variable=v3 core=ram_s2p_bram
for (int v4 = 0; v4 < 2; v4 += 1) { // L7, [0,4), iterCycle=1, II=1
#pragma HLS pipeline II=1
v2[v4] = 0.000000; // L8, [0,1)
}
for (int v5 = 0; v5 < 2; v5 += 1) { // L10, [4,40), iterCycle=26, II=8
#pragma HLS pipeline II=8
float v6 = v0[v5][0]; // L11, [0,2)
float v7 = v1[0]; // L12, [0,2)
float v8 = v6 * v7; // L13, [2,6)
float v9 = v8 + 0.000000; // L14, [6,11)
float v10 = v0[v5][1]; // L15, [5,7)
float v11 = v1[1]; // L16, [5,7)
float v12 = v10 * v11; // L17, [7,11)
float v13 = v9 + v12; // L18, [11,16)
v3[v5] = v13; // L19, [25,26)
float v14 = v2[0]; // L20, [18,20)
float v15 = v6 * v13; // L21, [16,20)
float v16 = v14 + v15; // L22, [20,25)
v2[0] = v16; // L23, [25,26)
float v17 = v2[1]; // L24, [18,20)
float v18 = v10 * v13; // L25, [16,20)
float v19 = v17 + v18; // L26, [20,25)
v2[1] = v19; // L27, [25,26)
}
}
This is interesting, thanks. I'll play around your example and see where's the issue.