问题描述
假设以下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和Max10 FPGA一起使用。
解决方法
检查名为“自动资源共享”的选项(在“高级合成器设置”中)已关闭。资源共享使合成器可以执行您不希望进行的加法器共享。
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
是加法器实例的标签。