我想以最少的更新和访问时间实现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);
我的问题:
答案 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 写的一些关于从一种编码域到另一种编码域(简而言之,不同的计算模型)的语义转换的有趣内容。
令我震惊的是,这可能是更一般意义上的实际递归表达式的起源点。但请注意,这非常困难。