Vivado HLS Synthesize error - PullRequest
       26

Vivado HLS Synthesize error

0 голосов
/ 10 мая 2018

В настоящее время я пытаюсь сделать какой-нибудь проект на Vivado HLS. Тем не менее, я получил ошибку, как показано в заголовке во время синтеза. Однако эта ошибка появляется:

ошибка: ** недопустимые операнды в двоичном выражении ('double' и 'datau32' (также известный как ap_axiu <32, 2, 5, 6> ')) imgOut = (0.2126 * Imgin [ordin] + 0.7152 * Imgin [ ordin + 1] + 0,0722 * Imgin [Координата + 2])

Это мой код HLS:

#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);
        }
    }
}

1 Ответ

0 голосов
/ 11 мая 2018

Инструмент жалуется, что не может работать с бинарными операторами в imgOut= (0.2126*Imgin[coord] + 0.7152*Imgin[coord+1] + 0.0722*Imgin[coord+2]).Бинарные операторы - это операторы с двумя операндами, здесь * и +.Как упоминалось в сообщении об ошибке, datau32 имеет тип ap_axiu<32, 2, 5, 6>.Imgin и imgOut имеют datau32 в качестве базового типа.Следовательно, сообщение, по-видимому, ссылается на умножения Imgin[...] с константами с плавающей запятой (0.2126 и т. Д.)

В любом случае, ap_axiu используется для объявления шин AXI.Это структура со следующим форматом (см. Стр. 110 в UG902 для Vivado HLS 2017.1.):

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 является еще одно double.double имеет ширину 64 бита, поэтому вам также придется устранить это несоответствие.Вы можете использовать константы типа float, что, скорее всего, достаточно точно.Или вы можете сделать свой автобус AXI шире.Или вы можете уменьшить точность после вычисления, приведя к float.Или вы можете использовать 2 цикла шины для передачи одного элемента.Обратите внимание, что если вы хотите преобразовать double или float в целое число, вам придется использовать reinterpret_cast, чтобы избежать потери точности.Обратите внимание, что вам также придется присваивать значения всем другим полям структуры ap_axiu.Обратите внимание, что вам также придется присваивать значения всем другим полям структуры ap_axiu (keep, strb и т. Д.).

Более простой способ использования шины AXI - объявление inStream и outStream как массивы, например ap_uint<32> inStream[320*240].О рукопожатии (TREADY и TVALID) автоматически позаботятся.Если вам нужен так называемый боковой канал (остальные сигналы, такие как TLAST или TUSER), вы не можете использовать этот метод.Это может иметь место, например, если вы хотите передавать пакеты данных вместо непрерывного потока (это можно сделать с помощью TLAST), или если ваш размер данных не кратен размеру шины, так что вам нужносигнал включения байта (TKEEP).

Я также могу представить, что вы никогда не намеревались использовать шину AXI.Существуют типы, такие как ap_uint и ap_fixed, которые можно использовать для передачи данных по простой шине.

Наконец, я хочу подчеркнуть, что вы всегда должны сначала отлаживать свой код в программном обеспечении .Есть много ошибок, которые трудно решить, основываясь только на результатах синтеза.Некоторые сообщения, как правило, указывают на людей в неправильном направлении.Я рекомендую сначала отладить свой код, используя функциональность симуляции Си.Кроме того, вы можете скомпилировать код вне Vivado HLS с помощью обычного компилятора C, такого как gcc.Я также рекомендую использовать средство проверки памяти, такое как valgrind, чтобы гарантировать, что ваш код не записывает внешние границы массива и т. Д. Инструмент не всегда находит эти проблемы, но приводит к неработоспособному оборудованию.

Iдумаю, что это решение, которое вы ищете:

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;
    }
  }
}
...