Как /= переводится на реальное оборудование в vhdl

Я новичок в программировании VHDL/FPGA. Я хочу сравнить два 32-битных std_logic_vector. В настоящее время я использую:

      if ( RX_FRAME(to_integer(s_data_counter)).Data /= REF_FRAME(to_integer(s_data_counter)).Data ) then
        s_bad_frame <= '1';
        state <= DONE;
      end if;

Здесь RX_FRAME и REF_FRAME - это 2 массива std_logic_vector(31 downto 0)

Я хочу знать, как инструмент синтеза переводит /= в аппаратное обеспечение. Целесообразно ли использовать это? Или я должен сделать XOR соответствующих векторов и проверить полученный вектор на наличие нулей? Если я сделаю XOR и сверюсь с нулями, не увеличится ли это количество необходимого оборудования? Я использую Vivado Design Suite 2015.3.


person Vinay Madapura    schedule 20.01.2016    source источник


Ответы (2)


Как уже представил Мортен, операции сравнения реализованы в таблицах LUT, выполняющих некоторую агрегацию X(N)OR и AND/(N)OR.

Но это могло бы быть быстрее...
FPGA имеют быстрые цепочки переноса, которые можно использовать для ускорения операций сравнения с широкими входными данными, но инструменты синтеза в основном не используют эти специальные ресурсы.

Как выполнить сравнение на равенство с помощью цепочки переноса?
Цепочки переноса можно реализовать как цепочки kill-propagate. Это название происходит от сумматоров с пульсирующим переносом, в которых перенос может быть сгенерирован, распространен из переноса или уничтожен.

Компаратор начинается с активного переноса (все равны). Каждый шаг вычисляется в LUT: An = Bn. Если да, распространите бит переноса, иначе убейте его.

Если перенос высокий (начальное значение пережило цепочку), все биты были равны.

Приложение для Мортена Зилмера

У меня нет примера кода для операции равно или неравно, но у меня есть аналогичный пример для операторов prefix and и prefix or, использующих цепочки переноса для ускорения вычислений для широких входных данных. .

  • prefix_and вычисляет: y(i) <= '1' when x(i downto 0) = (i downto 0 => '1') else '0'; Объяснение:
    Результирующий вектор равен 1, пока не будет найден первый 0, после чего он равен 0.
    Или, другими словами: первый ноль, найденный в позиции i при переходе от 0 to n убийства все оставшиеся биты независимо от входных битов.

  • prefix_or вычисляет: y(i) <= '0' when x(i downto 0) = (i downto 0 => '0') else '1';

    Объяснение:
    Результирующий вектор равен 0, пока не будет найден первый 1, после этого он будет 1.
    Или, другими словами: первый найденный в позиции i при переходе от 0 to n < strong>генерирует
    единицу и распространяет ее на все оставшиеся биты независимо от входных битов.

Следующий код представляет собой общее описание VHDL для prefix_and. Он не зависит от поставщика, но использует специальные примитивы (MUXCY) на ПЛИС Xilinx.

architecture rtl of arith_prefix_and is
begin
  y(0) <= x(0);
  gen1: if N > 1 generate
    signal  p : unsigned(N-1 downto 1);
  begin
    p(1) <= x(0) and x(1);
    gen2: if N > 2 generate
      p(N-1 downto 2) <= unsigned(x(N-1 downto 2));

      -- Generic Carry Chain through Addition
      genGeneric: if VENDOR /= VENDOR_XILINX generate
        signal  s : std_logic_vector(N downto 1);
      begin
        s <= std_logic_vector(('0' & p) + 1);
        y(N-1 downto 2) <= s(N downto 3) xor ('0' & x(N-1 downto 3));
      end generate genGeneric;

      -- Direct Carry Chain by MUXCY Instantiation
      genXilinx: if VENDOR = VENDOR_XILINX generate
        component MUXCY
          port (
            S  : in  std_logic;
            DI : in  std_logic;
            CI : in  std_logic;
            O  : out std_logic
          );
        end component;
        signal  c : std_logic_vector(N-1 downto 0);
      begin
        c(0) <= '1';
        genChain: for i in 1 to N-1 generate
          mux : MUXCY
            port map (
              S  => p(i),
              DI => '0',
              CI => c(i-1),
              O  => c(i)
            );
        end generate genChain;
        y(N-1 downto 2) <= c(N-1 downto 2);
      end generate genXilinx;

    end generate gen2;
    y(1) <= p(1);
  end generate gen1;
end architecture;

Источник: PoC.arith.prefix_and

person Paebbels    schedule 20.01.2016
comment
Можете ли вы добавить короткий пример кода VHDL, который, вероятно, сделает сопоставление инструмента синтеза с такой цепочкой распространения навыков; Требуется ли использование модулей, специфичных для технологии? - person Morten Zilmer; 21.01.2016
comment
@MortenZilmer добавил пример. Пожалуйста, свяжитесь со мной, если у вас есть дополнительные вопросы :). - person Paebbels; 21.01.2016
comment
Спасибо за пример, и я вижу, что проверка префикса (самый длинный 0/1) может выиграть от цепочки переноса. Но для цепочки время линейно (O(n) = n), где простое сравнение может быть древовидной структурой, где время логарифмично (O(n) = ln(n)). Поэтому я не считаю цепочку распространения навыков более быстрой заменой простого сравнения. - person Morten Zilmer; 22.01.2016
comment
Это связано с тем, что цепочки переноса имеют очень низкую задержку маршрутизации по сравнению с обычными проводами. Я использую prefix_and в реализации списка LRU, которая была намного быстрее после его использования. Поищу, если найду замеры. - person Paebbels; 22.01.2016
comment
Спасибо за обновление, и я запомню трюк для тайминга критического кода :-) - person Morten Zilmer; 22.01.2016
comment
Я просмотрел ответ и понял, как работает этот модуль. У меня все еще есть одно сомнение. т. е. Вход для этих модулей должен быть либо «ИСКЛЮЧАЮЩЕЕ ИЛИ» (для «prefix_and»), либо «ИСКЛЮЧАЮЩЕЕ ИЛИ» (для «prefix_or») двух сравниваемых широких векторов. И проверьте, чтобы MSB выхода был ВЫСОКИМ или НИЗКИМ соответственно. Я правильно понял? - person Vinay Madapura; 22.01.2016
comment
@VinayMadapura Да, в случае оператора равенства (xnor) вы предварительно вычисляете x(i) <= a(i) xnor b(i); или просто x <= a xnor b; в VHDL. Затем вы сравниваете каждый бит, но вы не знаете, заполнен ли полный вектор x единицами. Таким образом, вы используете prefix_and для проверки всех битов на единицы. Если перенос (MSB) вектора prifix_and y равен единице, то в векторе не было нуля. В то время как prefix_and сопоставляется с цепочкой переноса, операция xnor сопоставляется с LUT. Более того, поскольку вам не нужны промежуточные значения переноса, синтез может отображать 3 последовательных бита a и b в одну LUT6 Xilinx FPGA. - person Paebbels; 22.01.2016
comment
@VinayMadapura Таким образом, синтез должен вычислять y(i/3) <= (a(i+0) xnor b(i+ 0)) and (a(i+1) xnor b(i+1)) and (a(i+2) xnor b(i+2));, это сокращает цепочку переноса на 3. - person Paebbels; 22.01.2016

Вы должны сравнить с /=, чтобы действительно извлечь выгоду из такого языка, как VHDL, и передовых инструментов синтеза, таких как Xilinx Vivado.

Затем инструмент синтеза реализует это с помощью внутренних LUT в FPGA, возможно, с функцией, аналогичной вентилям XOR для переменных аргументов, или вентилям AND/NOT, если один из аргументов оценивается как константа. Лучший способ увидеть фактическую реализацию — это вызвать представление графического интерфейса в инструменте, который показывает реализованный дизайн.

Но начинать двойное угадывание инструмента, выполняя вентили XOR самостоятельно, обычно плохая идея, поскольку инструмент обычно намного лучше определяет наилучшую реализацию. Однако, если вы обнаружите, что инструмент не может идентифицировать конкретную конструкцию и выбрать эффективную реализацию, может быть хорошей идеей направить инструмент с большей реализацией, близкой к стилю кодирования, но для сравнения, такого как /=, это редко бывает.

person Morten Zilmer    schedule 20.01.2016