Использование LUT Artix-7 слишком велико для логики с 6 входами и 1 выходом - PullRequest
1 голос
/ 04 августа 2020

В 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;

Вот синтезированная схема c.

Схемати c

Когда я изменяю код, чтобы просто пропустить одно вычитание:

if (d_in(5 downto 4) * d_in(3 downto 0) = primes(i)) then
    d_out <= '1';
end if;

и синтезировать, я получаю ожидаемую 1 LUT использовано.

1 Ответ

1 голос
/ 05 августа 2020

Vivado, вероятно, действительно реализует некоторые арифметические c из вашей первой версии. Но отчасти это ваша вина: вы описали все это как простую arithmeti c, в то время как вам нужна постоянная справочная таблица. Почему бы не рассчитать вашу постоянную справочную таблицу, а затем использовать ее как есть? Следующее - это просто непроверенный черновик, чтобы показать вам пример этого функционально эквивалентного решения, но значительно отличающегося с точки зрения чистого синтеза:

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 константу, как это сделал бы симулятор, а затем использует ее для определения оборудования. Таким образом, достаточно простого LUT 6 к 1 вместо бесполезно сложной схемы на основе арифметики c.

Обратите внимание, что любая другая константа 64x1, даже произвольно сложная для вычисления, приведет к тому же использованию ресурсов после синтеза.

...