【发布时间】:2020-08-17 15:03:36
【问题描述】:
假设有以下 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。
【问题讨论】:
-
“在我看来这没有任何意义。”您的读者可能会更喜欢演示,这反映在逻辑元件利用率或性能上。根据用于每个加法器元素的 LUT 大小,有些器件系列中的多路复用器可能是“免费的”。您的第二个 sn-p 详细说明了两个进程,用于提供单独的映射工作的两个并发赋值语句。