Предотвратить совместное использование логики сумматора

Предположим, следующий компонент VHDL:

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity adder is
    port
    (
        iClk : in std_logic;

        iDataA : in unsigned(7 downto 0);
        iDataB : in unsigned(7 downto 0);
        iDataC : in unsigned(7 downto 0);

        oResultA : out unsigned(7 downto 0);
        oResultB : out unsigned(7 downto 0)
    );
end entity;

architecture behaviour of adder is
begin
    process
    begin
        wait until rising_edge(iClk);
        if iDataB /= 0 then
            oResultA <= iDataA + iDataB;
        else
            oResultB <= iDataA + iDataC;
        end if;
    end process;
end behaviour;

Как видно, он содержит два дополнения. Я ожидал, что синтезированная логика тоже будет содержать два сумматора. Вместо этого Quartus, кажется, считает хорошей идеей использовать только один сумматор и мультиплексировать в него второй вход (см. RTL ниже). На мой взгляд, в этом нет никакого смысла. Это не экономит аппаратные ресурсы, потому что для мультиплексора требуется такое же количество логических элементов, как и для сумматора. Кроме того, мультиплексор должен ждать, пока не будет оценено условие if, что приводит к худшему времени.

У меня такое случалось с гораздо большим компонентом и большим конечным автоматом, что приводило к нарушениям синхронизации. Как предотвратить такого рода «оптимизацию»? Я установил режим оптимизации «Производительность (Агрессивный — увеличивает время выполнения и площадь)», но, похоже, это не имеет значения. Единственное, что привело к ожидаемому результату, это введение дополнительных сигналов, например:

tmpA <= iDataA + iDataB;
tmpB <= iDataA + iDataC;

process
begin
    wait until rising_edge(iClk);
    if iDataB /= 0 then
        oResultA <= tmpA;
    else
        oResultB <= tmpB;
    end if;
end process;

Есть ли лучший способ сделать это, так как это делает код очень трудным для чтения. Я использую Quartus 20.1 с FPGA Max10.

RTL-представление: введите здесь описание изображения


person sebi707    schedule 17.08.2020    source источник
comment
На мой взгляд, в этом нет никакого смысла. Вашим читателям может быть более удобной демонстрация, которая отражает либо использование логических элементов, либо производительность. Существуют семейства устройств, в которых мультиплексор может быть «свободным» в зависимости от размера LUT, используемого для каждого элемента сумматора. Ваш второй фрагмент раскрывает два процесса для двух одновременных операторов присваивания, обеспечивающих отдельные усилия по сопоставлению.   -  person    schedule 18.08.2020


Ответы (1)


Убедитесь, что опция (в дополнительных настройках синтезатора) под названием «Автоматическое совместное использование ресурсов» отключена. Совместное использование ресурсов позволяет синтезатору выполнять такое совместное использование сумматоров, которое вы не хотите делать.

OR

Поместите свои сумматоры на другой уровень иерархии (т. е. в отдельный объект), а затем установите атрибут keep для предотвращения оптимизации:

attribute keep: boolean;
attribute keep of my_adder0: label is true;
attribute keep of my_adder1: label is true;

где my_adder0 и my_adder1 — это метки ваших экземпляров сумматора.

person Matthew Taylor    schedule 17.08.2020
comment
Спасибо, именно такой вариант я и искал. Знаете ли вы, можно ли установить настройки синтеза, подобные этой опции, для отдельных файлов VHDL? Мне немного страшно, когда я включаю эту опцию глобально для своего почти полного проекта. - person sebi707; 17.08.2020
comment
@ sebi707 Не знаю, извини. Однако можно синтезировать свой дизайн по частям. Это характерно для конструкций ИС, потому что обычно они больше. Таким образом, если вы запускаете Quartus из скрипта, вы можете отключить эту опцию при синтезе этого блока и включить при синтезе других блоков. - person Matthew Taylor; 18.08.2020