VHDL模拟陷入for循环

时间:2015-06-05 21:55:05

标签: loops vhdl multiplication

我正在为我编写的一些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乘法等...?

1 个答案:

答案 0 :(得分:1)

我认为在numeric_std函数调用中实现蒙哥马利乘数可能不会像你想要的那样改善模拟(同时给出综合资格)。

问题是动态详细说明的子程序调用数与其操作数大小相比,适用于CPU运行模型的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实现。

我在Stackoverflow问题(Montgomery multiplication VHDL Implementation)中找到了OpenCores实现,并在SVN存储库中找到了通用大小的版本(可下载的版本是16位),并在A 1024 – Bit Implementation of the Faster Montgomery Multiplier Using VHDL中提到了论文(由David Narh Anamor提供,原始链接已过期)。请注意引用的FPGA实现性能低于42 usec。

请注意,泛型指定的1024版本长度仍将执行动态详细的函数调用,长度为1024个操作数(尽管不是" *" s," mod" s或" /" s。您仍然在进行数百万次动态调用(通过表达式堆栈)1024位参数进行调用。我们只需更改数百万的大型数据参数子程序调用以及它们可以使用多长时间。

这也提出了在VHDL中实现整数向量(bignum等效)的可能性,这可能会进一步提高仿真性能(并且你可能在这里未知领域)。

使用可变参数的基于子程序的OpenCores模型版本将是有说服力的。 (无论你是否能给那些向他们展示仿真模型的人留下深刻的印象,或者这个懒散的停顿是否被所有人偷偷看了一眼挂钟并且看起来无聊而打断了)。