Функция clogb2(), сгенерированная vivado, не может синтезироваться с ошибкой ограничения цикла

Я пытаюсь разработать периферийное устройство AXI_master с помощью vivado. Я использовал генератор периферийных устройств axi в меню vivado и изменил сгенерированный код vhdl.

В коде vhdl есть функция clogb2, объявленная со следующим кодом:

function clogb2 (bit_depth : integer) return integer is
    variable depth  : integer := bit_depth;
    variable count  : integer := 1;
begin
  for clogb2 in 1 to bit_depth loop  -- Works for up to 32 bit integers
    if (bit_depth <= 2) then
      count := 1;
    else
      if(depth <= 1) then
          count := count;
        else
          depth := depth / 2;
        count := count + 1;
        end if;
    end if;
  end loop;
  return(count);
end;

Это работает в моделировании (GHDL), но не работает в синтезе с ошибкой:

[Synth 8-403] превышен лимит циклов (65538)

Я попытался увеличить лимит циклов в vivado с помощью следующей команды tcl:

set_param synth.elaboration.rodinMoreOptions "rt::set_parameter max_loop_limit <X>"

Как объяснено здесь, но vivado синтезирует с бесконечным временем и никогда не заканчивает. Вы знаете, как решить эту проблему?


person FabienM    schedule 23.06.2017    source источник


Ответы (4)


Вы также можете попробовать другой путь. Хотя логика с плавающей запятой не поддерживается (хотя поддержка увеличивается), она разрешена для внутренних вычислений и тому подобного. (По крайней мере, Xilinx и Altera/Intel).

Попробуй это:

use ieee.math_real.all;

function ceillog2(input : positive) return natural is
begin
    return integer(ceil(log2(real(input))));
end function;
person JHBonarius    schedule 23.06.2017

Попробуйте ограничить диапазон ввода, например:

function clogb2 (bit_depth : integer range 1 to 32) return integer is

Кроме того, если Vivado генерирует код, который не может скомпилировать, это ошибка, о которой вы должны сообщить на форумах Xilinx.

person scary_jeff    schedule 23.06.2017

Наконец я нашел решение, которое работает, переписав функцию с большим регистром:

function clogb2 (bit_depth : integer) return integer is
 begin
     case bit_depth is
         when 0 to 2             => return( 1);
         when (2** 1)+1 to 2** 2 => return( 2);
         when (2** 2)+1 to 2** 3 => return( 3);
         when (2** 3)+1 to 2** 4 => return( 4);
         when (2** 4)+1 to 2** 5 => return( 5);
         when (2** 5)+1 to 2** 6 => return( 6);
         when (2** 6)+1 to 2** 7 => return( 7);
         when (2** 7)+1 to 2** 8 => return( 8);
         when (2** 8)+1 to 2** 9 => return( 9);
         when (2** 9)+1 to 2**10 => return(10);
         when (2**10)+1 to 2**11 => return(11);
         when (2**11)+1 to 2**12 => return(12);
         when (2**12)+1 to 2**13 => return(13);
         when (2**13)+1 to 2**14 => return(14);
         when (2**14)+1 to 2**15 => return(15);
         when (2**15)+1 to 2**16 => return(16);
         when (2**16)+1 to 2**17 => return(17);
         when (2**17)+1 to 2**18 => return(18);
         when (2**18)+1 to 2**19 => return(19);
         when (2**19)+1 to 2**20 => return(20);
         when (2**20)+1 to 2**21 => return(21);
         when (2**21)+1 to 2**22 => return(22);
         when (2**22)+1 to 2**23 => return(23);
         when (2**23)+1 to 2**24 => return(24);
         when (2**24)+1 to 2**25 => return(25);
         when (2**25)+1 to 2**26 => return(26);
         when (2**26)+1 to 2**27 => return(27);
         when (2**27)+1 to 2**28 => return(28);
         when (2**28)+1 to 2**29 => return(29);
         when (2**29)+1 to 2**30 => return(30);
         when (2**30)+1 to (2**31)-1 => return(31);
         when others => return(0);
     end case;
 end;

С этой странной структурой кода, которая работает в синтезе и моделировании.

person FabienM    schedule 23.06.2017
comment
Вы смотрели на любой из других ответов? Это совсем не элегантное решение. - person scary_jeff; 23.06.2017

Эта рекурсивная версия синтезирует:

function clogb2 (bit_depth : integer) return integer is 
  begin
    if bit_depth <= 1 then
      return 0;
    else
      return clogb2(bit_depth / 2) + 1;
    end if;
  end function clogb2;

Вы можете использовать его для измерения других вещей, например

entity counter is
  generic (max_count : POSITIVE);
  port (clock, reset : in  std_logic;
        Q            : out std_logic_vector(clogb2(max_count) downto 0)  
       );
end;

или вы можете использовать его как комбинационную логику:

process (I)
begin
  O <= clogb2(I);
end process;

Кстати: вам лучше использовать целочисленный подтип для ввода:

function clogb2 (bit_depth : positive) return integer is 
--                               ^
--                               |
person Matthew Taylor    schedule 23.06.2017
comment
Но нравится ли вам ответ? clog2bee.vhdl:20:9:@0ms:(report note): clogb2 (112000) = 16. Для описания этого конкретного значения требуется двоичная длина 17. Вызов функции также должен иметь положительный диапазон. Отрицательное целое или нулевое значение никогда не достигнет bit_depth = 1. В зависимости от инструмента будет ограничение на рекурсию, он просто зациклится или у вас закончится стек вызовов. - person ; 23.06.2017
comment
@user1155120 user1155120 Мне нравится ответ: log2 из 112000 равно 16 в целочисленной математике. Исходная функция использовала положительный ввод — я изменил интерфейс и имя функции, чтобы они соответствовали вопросу. - person Matthew Taylor; 23.06.2017
comment
2 ** 16 равно 65536. Потолок (как в принятом ответе ceillog2) для удержания значения 112000 равен 2 ** 17 (131072), где 11200 находится между ними. Ваша функция предоставляет минимальное значение. В вашу защиту вопрос мог бы показать использование вызова функции. - person ; 23.06.2017
comment
Целочисленный тип с неопределенным начальным значением по умолчанию будет иметь значение integer'LEFT, которое является отрицательным числом. Недостаточно показать использование положительного подтипа в качестве фактического с меткой типа параметра, допускающей отрицательное значение. Я лично нашел симулятор, который вращает циклы, выполняющие рекурсивные вызовы, морально отвратительным, но не определяется как ошибка или ошибочный в соответствии со стандартом. - person ; 23.06.2017