云计算百科
云计算领域专业知识百科平台

HLS高层次综合设计--axi之burst纠偏

一、问题来源:https://zhuanlan.zhihu.com/p/478941270

二、具体代码
void ReadFeature(ap_uint<64> *feat_map, const TABLE_T *table, const uint32_t table_size,
    hls::stream<ap_uint<48>> &feat_word_strm)
{
    TABLE_T voxel_pt_num;
    TABLE_T pt_id = 0;

    for (uint32_t i = 0; i < table_size; ) {
        #pragma HLS PIPELINE II=1
        #pragma HLS LOOP_TRIPCOUNT min=204800 max=300000 avg=250000

        voxel_pt_num = table[i];

        // empty voxel
        if (voxel_pt_num == 0) {
            i++;
            pt_id = 0;
        }
        // non-empty voxel
        else {
            uint32_t offset = i * 32 + pt_id;
            ap_uint<64> feat_word = feat_map[offset];
            feat_word_strm.write(feat_word.range(47, 0).get());

            if (pt_id == (voxel_pt_num – 1)) {
                pt_id = 0;
                i++;
            }
            else {
                pt_id++;
            }
        }
    }
}

三、问题说明
1.这段代码文章博主说不能burst访问;
2.使用了outstanding优化,outstanding从4改为16,问题没有解决
3.使用了latency设置,将AXI的latency设置为40,解决了问题;

四、博主得到的结论是
1.使用指针实现AXI总线的顶层接口(尤其是访问DDR时)务必根据实际需要设置latency,影响巨大。
2.burst访问可以通过在for循环中顺次访问来实现,但是注意地址必须连续且不能在if分支中访问。
3.必要的时候可以使用memcpy来显式地指定burst。
4.希望未来能有某种接口可以独立地控制AXI的AR/AW通道与R/W通道,这样不必根据外部情况指定latency,也不必浪费相应的资源,设计的IP的适配性也更广。

五、说明
1.虽然博主设置axi latency=40解决了问题,但是还是没有本质解决;
2.上述代码就不能这么设计,burst访问不能有条件,这个是基本要求,也就是设计违规了;

六、burst案例一纠正
//////////// ORIGINAL ////////////
#include <ap_int.h>
void foo(ap_int<21> *a, ap_int<21> *b) {
  for (long i = 0; i < 256; ++i)
    b[i] = a[i];
}

//////////// UPDATED ////////////
// Use 'int' instead of 'ap_int<24>'
void foo(int *a, int *b) {
  for (long i = 0; i < 256; ++i)
    b[i] = a[i];
}
注意axi总线访问,不能是非32bit或者非64bit的

七、burst案例二纠正
//////////// ORIGINAL ////////////
void foo(volatile int *a, volatile int *b) {
  for (long i = 0; i < 256; ++i)
    b[i] = a[i];
}
 
//////////// UPDATED ////////////
void foo(int *a, int *b) {
  for (long i = 0; i < 256; ++i)
    b[i] = a[i];
}
volatile对总线进行了影响!!

八、burst案例三纠正
//////////// ORIGINAL ////////////
struct mystruct {
  char a;
  short b;
};
 
void foo(mystruct *a, mystruct *b) {
  for( int i = 0; i < 256; ++i )
    b[i] = a[i];
}
 
//////////// UPDATED ////////////
struct mystruct {
  char a;
  short b;
} __attribute__((packed, aligned(4)));
 
void foo(mystruct *a, mystruct *b) {
  for( int i = 0; i < 256; ++i )
    b[i] = a[i];
}

九、burst案例四纠正
//////////// ORIGINAL ////////////
void foo(int *a, int *b) {
  for (long i = 0; i < 256; ++i)
    b[i*4] = a[i*4] ;
}
 
//////////// UPDATED ////////////
// Use continuous accesses
void foo(int *a, int *b) {
  for (long i = 0; i < 256; ++i)
    b[i] = a[i] ;
}

十、burst案例五纠正
//////////// ORIGINAL ////////////
void foo(int *a) {
  int buff[256];
  for (long i = 0; i < 256; ++i) {
    if (i <= 6)
      buff[i] = a[i];
    …
  }
  …
}
 
//////////// UPDATED ////////////
// Remove conditional accesses
void foo(int *a) {
  int buff[256];
  for (long i = 0; i < 7; ++i)
    buff[i] = a[i];
 
  for (long i = 0; i < 256; ++i) {
    …
  }
  …
}

十一、burst案例六纠正
constexpr uint64_t N = 64;
 
//////////// ORIGINAL ////////////
void example(ap_int<24> a[N], ap_int<24> b[N]) {
#pragma HLS INTERFACE m_axi port = a depth = N bundle = gmem0
#pragma HLS INTERFACE m_axi port = b depth = N bundle = gmem1
  ap_int<24> buff[N];
  for (size_t i = 0; i < N; ++i) {
#pragma HLS PIPELINE II = 1
    buff[i] = a[i];
    buff[i] = buff[i] + 100;
    b[i] = buff[i];
  }
}
 
//////////// UPDATED ////////////
// Replace with power of 2 bits type.
void example(int a[N], int b[N]) {
#pragma HLS INTERFACE m_axi port = a depth = N bundle = gmem0
#pragma HLS INTERFACE m_axi port = b depth = N bundle = gmem1
  int buff[N];
  for (size_t i = 0; i < N; ++i) {
#pragma HLS PIPELINE II = 1
    buff[i] = a[i];
    buff[i] = buff[i] + 100;
    b[i] = buff[i];
  }
}

赞(0)
未经允许不得转载:网硕互联帮助中心 » HLS高层次综合设计--axi之burst纠偏
分享到: 更多 (0)

评论 抢沙发

评论前必须登录!