防止共享加法器逻辑

Prevent sharing of adder logic

假设有以下 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;

有没有更好的方法来做到这一点,因为它使代码很难阅读。我正在使用带有 Max10 FPGA 的 Quartus 20.1。

RTL 视图:

检查名为“自动资源共享”的选项(在高级合成器设置中)是否已关闭。资源共享使合成器能够执行您不想执行的 adder-sharing。

将你的加法器放在不同的层次结构层中(即在单独的实体中),然后设置一个属性以防止它被优化,称为 keep:

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

其中 my_adder0my_adder1 是加法器实例的标签。