vhdl - 6 输入 1 输出逻辑的 Artix-7 LUT 使用率过高
问题描述
在 Artix-7 上,一个 LUT 是 6 位输入,1 位输出。据推测,我拥有的任何具有 6 位输入、1 位输出的功能,我都可以通过仅使用一个 LUT 来实现。
然而,当我合成以下代码时,我收到一个报告说7 个 LUT已被使用。我想知道为什么?
我正在使用 Vivado 2019.2。
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.numeric_std_unsigned.all;
entity test is
port(
d_in : in std_logic_vector(5 downto 0);
d_out : out std_logic
);
end entity test;
architecture RTL of test is
type t_int_array is array (natural range<>) of integer;
constant primes : t_int_array(0 to 17) := (2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61);
begin
process(d_in)
begin
d_out <= '0';
for i in 0 to 17 loop
if (d_in(5 downto 4) * d_in(3 downto 0) - d_in(0) = primes(i)) then
d_out <= '1';
end if;
end loop;
end process;
end architecture RTL;
这是合成的示意图。
当我将代码更改为只跳过一个减法时:
if (d_in(5 downto 4) * d_in(3 downto 0) = primes(i)) then
d_out <= '1';
end if;
和综合,我得到了预期的1 LUT使用。
解决方案
Vivado 可能确实在您的第一个版本中实现了一些算法。但这部分是您的错:您将所有这些描述为简单的算术,而您想要一个恒定的查找表。为什么不计算您的常量查找表,然后按原样使用它?以下只是一个未经测试的草稿,向您展示了这个功能等效解决方案的示例,但从纯综合的角度来看却有很大不同:
type lut6to1_t is array(0 to 63) of std_ulogic;
function is_prime_f return lut6to1_t is
variable l: lut6to1_t := (others => '0');
variable p: natural range 0 to 63;
begin
for i in l'range loop
p := ((i / 16) * (i mod 16) - (i mod 2)) mod 64;
for j in primes'range loop
if p = primes(j) then
l(i) := '1';
end if;
end loop;
end loop;
return l;
end function is_prime_f;
constant is_prime: lut6to1_t := is_prime_f;
begin
d_out <= is_prime(d_in);
end architecture rtl;
主要区别在于合成器首先is_prime
像模拟器一样计算常数,然后使用它来推断硬件。因此,一个简单的 6 比 1 LUT 就足够了,而不是一个无用的复杂的基于算术的电路。
请注意,任何其他 64x1 常数,即使是任意复杂的计算,在综合后都会导致相同的资源使用。
推荐阅读
- python - 如何从 django api 视图中的模型中获取字段
- c# - 如何在实体框架 6 中编写 IQueryable 连接
- angularjs - Angularjs $location.path 未定义
- python-3.x - 将符号和模式添加到 Python 中的嵌套列表中?
- reactjs - 如何在 React 中偏移链接和锚点?
- html - dt dd 之间有换行符
- ajax - 什么是变量 [[FunctionLocation]]、[[Scopes]]:在浏览器控制台中
- python - Python:并行 Neo4J 批量写入
- c++ - 实现同步原语的原子的较小类型,例如信号量、互斥体或屏障
- cookies - 为什么“rust cookie::CookieJar”可以通过str类型取值