компиляция fphdl в Altera Quartus Prime

я попытался скомпилировать свой дизайн, использующий библиотеки fphdl http://www.eda.org/fphdl/ для операций с плавающей запятой. Хотя в modelsim симуляция нормально, при синтезе в Quartus hdl компилятор жалуется на утверждение:

result := to_integer (fract (frac'high downto frac'high-base))

по причине: «выражение не является постоянным», просматривая похожие сообщения, я понимаю, что этому компилятору не нравится, что frac'high-base не ограничен. Я попытался ограничить все связанные сигналы следующим образом:

variable frac    : UNSIGNED (23 downto 0);  
variable base    : INTEGER range 0 to 23;

но по-прежнему ошибка продолжается ... есть ли какое-либо решение для этого на уровне HDL или в самом Quartus?


person user2609910    schedule 27.02.2016    source источник


Ответы (2)


Обратите внимание, что в сообщении об ошибке говорится:

выражение не является постоянным

и не:

... ограничено

Таким образом, причина сообщения об ошибке заключается в том, что функция to_integer не может быть синтезирована, когда диапазон от fract является переменным во время выполнения, а не фиксированным во время разработки.

Обходом для Quartus может быть:

variable part : UNSIGNED(23 downto 0);
...
part := (others => '0');
part(base downto 0) := frac(frac'high downto frac'high - base);
result := to_integer(part);

Затем извлеченная часть из frac обнуляется, а длина вектора, заданная для to_integer, затем фиксируется, что позволяет синтезировать Quartus.

person Morten Zilmer    schedule 27.02.2016
comment
похоже, это работает. Я пытался сделать что-то подобное, но, возможно, я неправильно объявил временную переменную части, и ошибка перемещалась в этот оператор ... но ваш код проходит синтез. Спасибо! - person user2609910; 28.02.2016

Фрагмент кода в вопросе не имеет прямого отношения к пакетам fphdl. Это не зависит от каких-либо типов, объявленных в любом из них.

Выражение дает целое число result из frac с frac'HIGH - base "битами" точности.

Эквивалент исходного выражения может быть:

    variable dist:  integer range 0 to 23;

    dist := frac'HIGH - base;
    result := to_integer (SHIFT_RIGHT(frac, dist));

SHIFT_RIGHT исходит из пакета библиотеки IEEE numeric_std, используемого, потому что frac является беззнаковым.

Проницательный наблюдатель может заметить, что это эквивалент целочисленного деления на степень двойки, которое обычно поддерживается синтезом, обеспечивая более или менее идентичное оборудование.

И примерно здесь вы можете подумать, что ваш оператор - это мультиплексор со сдвинутыми входами, заполненными нулями, и все это подлежит оптимизации.

Исторически IEEE Std 1076.6-2004 (отозван) 8.6.5 Имена слайсов предоставлены -

Для дискретного диапазона, который появляется как часть имени среза, границы дискретного диапазона должны быть указаны прямо или косвенно как статические значения, принадлежащие целочисленному типу.

Мортен сказал нам, что Квартус Прайм может справиться с

    part := (others => '0');
    part(base downto 0) := frac(frac'high downto frac'high - base);
    result := to_integer(part);

где base не статичен (хотя вы могли подумать, что это должно быть ограничено).

Для тех инструментов синтеза, которые не могут работать с нестатическим дискретным диапазоном, то же самое можно сделать в цикле for в зависимости от параметра цикла , который является константой в развернутом цикле:

    part := (others => '0');
    for i in part'range loop
        if i = b then
            part(i downto 0) := frac(frac'high downto frac'high - i);
        end if;
    end loop;
    result := to_integer(part);

IEEE Std 1076 = 2008 10.10 Loop statement сообщает нам:

Для оператора цикла со схемой итерации for спецификация параметра цикла представляет собой объявление параметра цикла с заданным идентификатором. Параметр цикла - это объект, тип которого является базовым типом дискретного диапазона. В последовательности операторов параметр цикла является константой.

Цикл for дает тот же результат и должен производить такое же оборудование.

person Community    schedule 28.02.2016