首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Vivado HLS综合误差

Vivado HLS综合误差
EN

Stack Overflow用户
提问于 2018-05-10 10:26:07
回答 1查看 1.3K关注 0票数 2

我目前正在尝试做一些关于Vivado HLS的项目。但是,我得到了一个错误,如合成过程中的标题所示。但是,出现了以下错误:

错误:**二进制表达式('double‘和'datau32’(又名'ap_axiu<32,2,5,6>‘) imgOut= (0.2126*Imgincoord + 0.7152*Imgincoord+1 + 0.0722*Imgincoord+2)的无效操作数

这是我的HLS密码:

代码语言:javascript
复制
#include "core.h"

void imgreading(hls::stream<datau32> &inStream, datau32 Imgin[imagesize])
{
    for(int i=0;i<imagesize;i++)
    {
        Imgin[i]=(datau32)inStream.read();
    }
}

void resize_half(hls::stream<datau32> &inStream, hls::stream<datau32> &outStream)
{
#pragma HLS INTERFACE axis port=inStream
#pragma HLS INTERFACE axis port=outStream
#pragma HLS INTERFACE s_axilite port=return bundle=CRTL_BUS
    datau32 Imgin[imagesize];
    imgreading (inStream,Imgin);
    datau32 imgOut;
    int coord=0;


#pragma HLS DATAFLOW
    for (int a=0; a<240; a++) {
        for(int b=0; b<320; b++){
#pragma HLS PIPELINE II=1
            coord=6*(a*640+b);
            imgOut=  (0.2126*Imgin[coord] + 0.7152*Imgin[coord+1] + 0.0722*Imgin[coord+2]) ;
            datau32 dataOutSideChannel;
            dataOutSideChannel.data = imgOut;
            outStream.write (dataOutSideChannel);
        }
    }
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-05-11 12:00:04

这些工具抱怨它不能处理imgOut= (0.2126*Imgin[coord] + 0.7152*Imgin[coord+1] + 0.0722*Imgin[coord+2])中的二进制操作符。二进制运算符是两个操作数的操作符,这里是*+。正如错误消息中提到的,datau32ap_axiu<32, 2, 5, 6>类型的。ImginimgOutdatau32作为基本类型。因此,消息似乎是指Imgin[...]与浮点常量(0.2126等)的乘法。

无论如何,ap_axiu是用来声明AXI总线的。它是一个具有以下格式的结构(关于Vivado HLS 2017.1,请参见UG902第110页):

代码语言:javascript
复制
template<int D,int U,int TI,int TD>
struct ap_axiu{
  ap_uint<D> data;
  ap_uint<D/8> keep;
  ap_uint<D/8> strb;
  ap_uint<U> user;
  ap_uint<1> last;
  ap_uint<TI> id;
  ap_uint<TD> dest;
};

所以你要做的是用一个结构乘以一个浮点常量。这在C++中是不允许的。

如果您打算使用AXI总线,则必须使用结构的data字段来传递数据。将整数data字段与double相乘的结果是另一个doubledouble是64位宽,所以你也必须处理这个差异。您可以使用float类型的常量,这可能足够精确。或者你可以把你的AXI巴士加宽。或者您可以通过转换到float来降低计算后的精度。或者您可以使用两个总线周期来传输单个元素。请注意,如果要将doublefloat转换为整数,则必须使用reinterpret_cast以避免丢失精度。请注意,您还必须为ap_axiu结构的所有其他字段赋值。请注意,您还必须为ap_axiu结构的所有其他字段(keepstrb等)赋值。

使用AXI总线的一种更简单的方法是将inStreamoutStream声明为数组,例如ap_uint<32> inStream[320*240]。握手(TREADYTVALID)是自动处理的。如果您需要所谓的侧信道(剩下的信号如TLASTTUSER),则不能使用此方法。例如,如果您想要传输数据包而不是连续流(可以使用TLAST完成),或者如果您的数据大小不是总线大小的倍数,则需要一个字节启用信号(TKEEP)。

我还可以想象,您从未打算使用AXI总线。有些类型(如ap_uintap_fixed )可用于在普通总线上提交数据。

最后,我想强调的是,--您应该始终在软件优先中调试您的代码。有许多错误是很难解决的基础上的综合输出。有些信息往往指向错误的方向。我建议您首先使用C模拟功能调试代码。或者,您可以使用常规C编译器(如gcc )在Vivado HLS之外编译代码。我还建议使用内存检查器(如valgrind )来确保代码不会编写外部数组边界等。该工具并不总是发现这些问题,但它确实会导致无法使用的硬件。

我认为这是你正在寻找的解决方案:

代码语言:javascript
复制
void resize_half(ap_uint<32> inAXI[640 * 480 * 3], ap_uint<32> outAXI[320 * 240])
{
#pragma HLS INTERFACE axis port=inAXI
#pragma HLS INTERFACE axis port=outAXI
#pragma HLS INTERFACE s_axilite port=return bundle=CRTL_BUS

#pragma HLS dataflow
  hls::stream<ap_uint<32> > Stream[3];
  for (int i = 0; i < 480; i++)
    for (int j = 0; j < 640; j++)
      for (int k = 0; k < 3; k++)
      {
#pragma HLS PIPELINE II=1
        ap_uint<32> value = inAXI[3 * (640 * i + j) + k];
        if (i % 2 == 0 && j % 2 == 0)
          Stream[k].write(value);
      }

  for (int a = 0; a < 240; a++)
  {
    for (int b = 0; b < 320; b++)
    {
#pragma HLS PIPELINE II=1
      ap_uint<32> x = Stream[0].read();
      ap_uint<32> y = Stream[1].read();
      ap_uint<32> z = Stream[2].read();
      outAXI[320 * a + b] = 0.2126 * x + 0.7152 * y + 0.0722 * z;
    }
  }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50270744

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档