可合成的VHDL递归,Vivado:模拟器已意外终止

时间:2019-08-22 06:09:36

标签: vhdl simulation vivado synthesis

我想以最少的更新和访问时间实现count min sketch

基本上,输入样本由多个(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);

我的问题:

  • 为什么我不能模拟此代码?
  • 此代码在工作后是否可以合成?
  • 是否有更好(和/或更快)的方法来获取所有相关哈希桶中的最小值?

2 个答案:

答案 0 :(得分:2)

并不是说我能够找到现实世界中用于递归的任何方法,而只是让@EML感到惊讶(如上面的注释中所述):您实际上可以可以在VHDL中定义递归硬件结构。 / p>

至少在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的单个组合电路(因此,实际用途可能非常受到限制),但至少可以正常工作。

答案 1 :(得分:0)

在 VHDL 中可以递归吗?

我会说,是的,但不是我们所知道的递归。这就是简短的回答。我有代码(如果有人对实现 Quicksort 感兴趣),它会很高兴地合成。如果有人知道 Quicksort,它通常不会接近综合的上下文。但我设法做到了。

诀窍(令人烦恼且难以理解)是使用一个奇怪的状态机模拟递归,该状态机在将“状态”推送到(硬件)堆栈上后回溯到起始状态。如果你愿意,你可以很容易地合成这种数据结构。

我记得 Thatcher、Goguen 和 Wright 写的一些关于从一种编码域到另一种编码域(简而言之,不同的计算模型)的语义转换的有趣内容。

令我震惊的是,这可能是更一般意义上的实际递归表达式的起源点。但请注意,这非常困难。