现在我正在尝试找出在FPGA中迭代位的最佳方法。我正在使用快速供电算法的一些变体,通过平方的a.k.a指数化(更确切地说,它是椭圆曲线数学的加倍和加法算法)。要在硬件上实现它,我知道我必须使用进行迭代的FSM。我的问题是如何正确地“处理”从一点一点移动。我的第一个想法是切换字节顺序,但是当我的k = 17是32位时,我必须丢弃前27位,所以这是相当愚蠢的想法。另一个概念是“移动”0001000模式和按位&它有数字,但它也需要找到第一个非零位。
TL&安培; DR 得到例如k = 17(32位,所以:17x0 10001)并且想要迭代5次(这意味着我开始迭代第一个“实数”位数)知道我迭代的每个位。
语言并不重要 - 我只需要算法,而不是特定语言的解决方案。但是,如果在Verilog中轻松完成,我不介意。 :P
答案 0 :(得分:0)
不要为FPGA编码,但仍然:
这样你就可以在主循环中进行位扫描,而不需要额外的循环。
C ++代码示例:
DWORD x = ...;
for (; x != 0; x >>= 1)
{
//here is your iteration loop stuff like:
if (DWORD(x & 1) !=0 ) ...;
}
答案 1 :(得分:0)
一个专用的组合电路,用于找到第一个非零位,将其移至第一个位置并告诉您移位量对资源的影响相当小。
原则上,编译器应该能够自己找到这个解决方案并对其进行改进:
if none of the top 16 bits are set, set bit 4 of the shift amount, and shift by 16.
if none of the top 8 bits are set, set bit 3 of the shift amount, and shift by 8.
...
编译器应该能够在此找到进一步的优化。
答案 2 :(得分:0)
类似的东西:
always @ *
casex(num)
8XXX_XXXX: k = 32;
4XXX_XXXX: k = 31;
2XXX_XXXX: k = 30;
...
应该给你k的值。
你可以有一个可以并行加载的移位寄存器,这样你就可以在第k位写1,所以你知道你的迭代何时结束。
答案 3 :(得分:0)
如果你从0循环到31并丢弃27个前导零......你不一定要浪费周期。取决于您是使用同步过程还是异步过程包围它。
One为您提供了一个相当小的时钟电路,具有32个时钟延迟。 另一个给你一个巨大的大鼠巢ANDs和ORs,它们不会以非常高的频率运行。
取决于你想要什么。但请记住,即使你决定循环超过32个时钟,你也可以使用PIPELINE,以便每个时钟开始一个新的计算。你可能需要32个时钟才能得到答案,但你可以高速完成它们。