Синтезируемая рекурсия VHDL, Vivado: симулятор неожиданно завершил работу

Я хотел бы реализовать набросок count min с минимальным обновлением и доступом раз.

По сути, входная выборка хэшируется несколькими хеш-функциями (d), и каждая из них увеличивает счетчик в сегменте, в который попадает. При запросе выборки счетчики всех сегментов, соответствующих выборке, сравниваются, и в результате возвращается значение наименьшего счетчика.

Я пытаюсь найти минимальное значение счетчиков за log_2(d) времени с помощью следующего кода:

entity main is
Port (    rst : in STD_LOGIC;
          a_val : out STD_LOGIC_VECTOR(63 downto 0);
          b_val : out STD_LOGIC_VECTOR(63 downto 0);
          output : out STD_LOGIC_VECTOR(63 downto 0);
             .                               .
             .                               .
             .                               .
          CM_read_ready : out STD_LOGIC;
          clk : in STD_LOGIC);
end main;

architecture Behavioral of main is

    impure function min( LB, UB: in integer; sample: in STD_LOGIC_VECTOR(long_length downto 0)) return STD_LOGIC_VECTOR is
        variable left : STD_LOGIC_VECTOR(long_length downto 0) := (others=>'0');
        variable right : STD_LOGIC_VECTOR(long_length downto 0) := (others=>'0');

    begin

        if (LB < UB)
        then
            left := min(LB, ((LB + UB) / 2) - 1, sample);
            right := min(((LB + UB) / 2) - 1, UB, sample);

            if (to_integer(unsigned(left)) < to_integer(unsigned(right)))
            then
                return left;
            else
                return right;
            end if;
        elsif (LB = UB)
        then
            -- return the counter's value so that it can be compared further up in the stack.
            return CM(LB, (to_integer(unsigned(hasha(LB)))*to_integer(unsigned(sample)) 
                            + to_integer(unsigned(hashb(LB)))) mod width);
        end if;
    end min;

begin

    CM_hashes_read_log_time: process (clk, rst)
    begin
        if (to_integer(unsigned(instruction)) = 2)
            then
                output <= min(0, depth - 1, sample);
            end if;
        end if;
    end process;
end Behavioral;

Когда я запускаю приведенный выше код, я получаю следующие ошибки:

Симулятор неожиданно завершил работу. Подробности смотрите в журнале моделирования (xsim.log).

[USF-XSim-62] Шаг компиляции завершился неудачно с ошибкой(ами). Пожалуйста, проверьте вывод консоли Tcl или файл '/home/...sim/sim_1/behav/xsim/xvhdl.log' для получения дополнительной информации.

[USF-XSim-62] Шаг «усложнения» не выполнен с ошибкой(ами). Пожалуйста, проверьте вывод консоли Tcl или файл '/home/...sim/sim_1/synth/func/xsim/elaborate.log' для получения дополнительной информации.

Мне не удалось найти ни одного файла с именем xsim.log, а xvhdl.log был пуст, но elaborate.log содержал некоторый контент:

Vivado Simulator 2018.2
Copyright 1986-1999, 2001-2018 Xilinx, Inc. All Rights Reserved.
Running: /opt/Xilinx/Vivado/2018.2/bin/unwrapped/lnx64.o/xelab -wto c199c4c74e8c44ef826c0ba56222b7cf --incr --debug typical --relax --mt 8 -L xil_defaultlib -L secureip --snapshot main_tb_behav xil_defaultlib.main_tb -log elaborate.log 
Using 8 slave threads.
Starting static elaboration
Completed static elaboration
INFO: [XSIM 43-4323] No Change in HDL. Linking previously generated obj files to create kernel

Удаление следующей строки устраняет вышеуказанные ошибки:

output <= min(0, depth - 1, sample);

Мои вопросы:

  • Почему я не могу смоделировать этот код?
  • Будет ли этот код синтезируемым после того, как он заработает?
  • Есть ли лучший (и/или более быстрый) способ получить минимум всех соответствующих хеш-баг?

person Chandran Goodchild    schedule 22.08.2019    source источник
comment
Различные вещи не так. sample и depth не существуют как сигнал/переменная в коде, поэтому их нельзя передать в функцию min. У процесса есть часы и сброс в списке чувствительности, но они не используются в процессе (так что это НЕ синхронный процесс), long_length не существует. hasha и hashb не существуют. Пожалуйста, предоставьте MCVE   -  person Tricky    schedule 22.08.2019
comment
Рекурсия обычно не рекомендуется для синтеза, так как может быть неясно, какова цель схемы. Особенно, когда рекурсия является функцией без возможности конвейерной обработки.   -  person Tricky    schedule 22.08.2019
comment
Проблема, которая, скорее всего, проблема: ваша функция min не всегда возвращает значение — нет предложения else для обработки случая LB > UB. Почти наверняка поэтому код не скомпилируется. Проблема, которая также является проблемой: ваша функция min не должна быть impure. См. этот справочник, в котором описываются различия между чистыми и нечистыми функциями в VHDL: vhdlwhiz.com/function   -  person Mr. Snrub    schedule 22.08.2019
comment
... но, как указал @Tricky, после того, как вы исправите функцию min, у вас все равно будут проблемы. Я ожидаю, что ваш код будет скомпилирован в этот момент, но он все равно не будет работать так, как вы ожидали (ваш процесс CM_hashes_read_log_time не будет иметь желаемого временного поведения) из-за других проблем в коде.   -  person Mr. Snrub    schedule 22.08.2019
comment
Вы не могли «запустить приведенный выше код»; там полно ошибок. Опубликуйте что-нибудь, что хотя бы компилируется, а затем терпит неудачу при доработке или во время выполнения. Другими словами, как минимум xvhdl должен завершиться без ошибок.   -  person EML    schedule 22.08.2019
comment
Спасибо за все советы. Я наделал много ошибок, пытаясь сделать код минимальным. Мне больше не нужна эта функция, потому что я генерирую HDL-код с помощью скрипта Python, но я все равно хотел бы продолжить рекурсию. Должен ли я удалить свой вопрос и опубликовать его повторно, если у меня есть MCVE?   -  person Chandran Goodchild    schedule 23.08.2019
comment
Если вы просто хотите узнать о рекурсии: в целом, для синтеза нормально, если ваша функция выполняется во время синтеза, эквивалентного обработке. Другими словами, это должно быть частью настройки модели; вы можете использовать его, например, для установки содержимого ПЗУ. Однако все ставки сняты, если требуется превратиться в настоящие ворота. Маловероятно, что какой-либо синтезатор справится даже с тривиальной рекурсивной аппаратной структурой, но я готов удивиться.   -  person EML    schedule 23.08.2019
comment
@EML: см. ответ ниже (просто чтобы вас удивить) ;)   -  person mfro    schedule 24.08.2019


Ответы (2)


не то чтобы я смог найти какое-либо реальное применение рекурсии, но просто чтобы удивить @EML (как просили в комментариях выше): вы действительно можете определять рекурсивные аппаратные структуры в VHDL.

По крайней мере, в Quartus это работает только в том случае, если вы даете компилятору четкое указание максимальной глубины рекурсии, иначе он попытается развернуть рекурсию на любой возможный вход, в конечном итоге умирая от переполнения стека:

entity recursive is
    generic
    (
        MAX_RECURSION_DEPTH  : natural
    );
    port
    (
        clk     : in std_ulogic;
        n       : in natural;
        o       : out natural
    );
end recursive;

architecture Behavioral of recursive is
    function fib(max_depth : natural; n : natural) return natural is
        variable res : natural;
    begin
        if max_depth <= 1 then
            res := 0;
            return res;
        end if;
        if n = 0 then
            res := 0;
        elsif n = 1 or n = 2 then
            res := 1;
        else
            res := fib(max_depth - 1, n - 1) + fib(max_depth - 1, n - 2);
        end if;
        return res;
    end function fib;
begin
    p_calc : process
    begin
        wait until rising_edge(clk);
        o <= fib(MAX_RECURSION_DEPTH, n); 
    end process;
end Behavioral; 

При MAX_RECURSION_DEPTH, равном 6, получается одна комбинационная схема с более чем 500 LE (поэтому практическое использование, вероятно, очень ограничено), но, по крайней мере, это работает.

person mfro    schedule 23.08.2019
comment
Рекурсия в структуре также может быть пригодным для синтеза с использованием общих констант для ограничения «глубины» в дополнение к рекурсивным вызовам функций с ограниченной глубиной. - person ; 24.08.2019
comment
@ user1155120 спасибо за связанный ответ, он умный. К сожалению, Quartus II недостаточно умен, чтобы скомпилировать его (поскольку он не позволяет дженерикам ссылаться на другие дженерики в том же списке интерфейсов). - person mfro; 24.08.2019
comment
Вот твоя проблема. Как отмечено в ответе, есть две функции, доступные только в -2008, и Quartus II несовместим. Обратите внимание, что в вопросе ОП здесь упоминается Vivado. - person ; 24.08.2019
comment
Ага, удивил... :) - person EML; 25.08.2019

Возможна ли рекурсия в VHDL?

Я бы сказал, да, но не рекурсия, как мы ее знаем. Это короткий ответ. У меня есть код (если кому-то интересно, который реализует Quicksort), и он вполне успешно синтезируется. Если кто-то знает о быстрой сортировке, обычно это не будет близко к контексту синтеза. Но мне удалось это сделать.

Уловка (которая досадна и трудна для понимания) состоит в том, чтобы эмулировать рекурсию со странным конечным автоматом, который возвращается к начальному состоянию после помещения состояния в (аппаратный) стек. Вы можете довольно легко синтезировать такую ​​структуру данных, если хотите.

Я вспоминаю кое-что интересное, написанное Тэтчер, Гогеном и Райтом о семантических преобразованиях из одного вида домена кодирования в другие (короче говоря, разные модели вычислений).

Мне кажется, что это, возможно, точка зарождения реальных рекурсивных выражений в более общем смысле. Но будьте осторожны, это очень сложно.

person Mark Grindell    schedule 15.07.2021
comment
Это не дает ответа на вопрос. Получив достаточную репутацию, вы сможете /comment">прокомментировать любой пост; вместо этого дайте ответы которые не требуют разъяснений от спрашивающего. – Из обзора - person Calculuswhiz; 19.07.2021