VHDL仿真陷入for循环

VHDL simulation stuck in for loop

我正在对我编写的一些 VHDL 进行模拟测试,当我 运行 它在 ModelSim 中时它卡住了。当我点击 'break' 时,它有一个箭头指向以下函数中的 For 循环:

function MOD_3 (a, b, c : UNSIGNED (1023 downto 0)) return UNSIGNED is

  VARIABLE x : UNSIGNED (1023 downto 0) := TO_UNSIGNED(1, 1024);
  VARIABLE y : UNSIGNED (1023 downto 0) := a;
  VARIABLE b_temp : UNSIGNED (1023 downto 0) := b;

begin

  for I in 0 to 1024 loop
    if b_temp > 0 then
      if b_temp MOD 2 = 1 then
        x := (x * y) MOD c;
      end if;
      y := (y * y) MOD c;
      b_temp := b_temp / 2;
    else
      exit;
    end if;
  end loop;

  return x MOD c;

end function;

我最初将其作为 while 循环使用,但我意识到它不适合合成。所以我将它转换为一个 for 循环,条件是 b_temp 大于 0。b_temp 是一个 1024 位 unsigned 所以如果它是最大的数字可以用 1024 位表示并分成两半(我在每次迭代中这样做)1024 次,它不应该肯定是 0 吗?

我觉得我的问题在于大乘法...如果我注释掉 x := (x * y) MOD cy := (y * y) MOD c 然后它退出循环。所以我唯一能想到的是执行这些1024位乘法需要太长时间吗?如果是这种情况,是否有任何内置方法可以优化它以使其更快,或者我唯一的选择是实现像 Karatsuba 乘法等...?

我认为在 numeric_std 函数调用中实现蒙哥马利乘法器可能无法像您希望的那样改善模拟(同时提供综合资格)。

问题是动态阐述的子程序调用的数量与它们的操作数大小与适合您的 CPU-运行-Modelsim 的 L1/L2/L3 缓存。

它确实为 FPGA 或 SIMD GPU 实现中的目标合成创造了奇迹。

参见 Subversion Repositories BasicRSA 文件 modmult.vhd(具有通用尺寸)。我成功地将其转换为使用 numeric_std[_unsigned].

如果我没记错的话,这似乎受到了启发 David Narh Amanor 在 2005 年的硕士论文 (Efficient Hardware Architectures for Modular Multiplication) 概述了 Java 和各种字长的 VHDL 实现。

我发现了 Whosebug 问题中提到的 OpenCores 实现(Montgomery multiplication VHDL Implementation) and found the generic sized version in the SVN repository (the downloadable version is 16 bit) and the mention of the thesis in A 1024 – Bit Implementation of the Faster Montgomery Multiplier Using VHDL(David Narh Anamor,原来的 link 已过期)。注意引用的 FPGA 实现在 42 usec 下的性能。

请注意,由泛型指定的长度为 1024 的版本仍将执行具有长度为 1024 操作数的动态详细函数调用(尽管不是“*"s, the "mod"s or the "/”s 。你仍然会用动态阐述的(在表达式堆栈上传递)1024 位参数进行数百万次函数调用。我们只是改变了多少百万次大参数子例程调用以及它们可以花费多长时间。

这也带来了在 VHDL 中实现整数向量(bignum 等价物)的可能性,这可能会进一步提高仿真性能(您可能处于未知领域)。

使用可变参数的基于子程序的 OpenCores model 版本会说明问题。 (无论您能否给任何人留下深刻印象,向他们展示模拟 model 正在执行,或者是否有这个 looong 停顿被每个人偷偷瞥了一眼挂钟并看起来很无聊)。