如何用VHDL加速我的数学运算?

如何用VHDL加速我的数学运算?,vhdl,fpga,Vhdl,Fpga,我有一些计算正在进行,目前在一个75兆赫的像素时钟上升沿,以输出720p的视频在屏幕上。一些数学运算(比如一些模运算)花费的时间太长(20+ns,而75MHz是13.3ns),所以我的时间限制没有得到满足。我不熟悉FPGA,但我想知道是否有一种方法可以以比当前像素时钟更快的速度运行计算,以便在75MHz时钟的下一个滴答声之前完成计算。顺便说一下,我正在使用VHDL。FPGA中的复杂数学运算通常是流水线的。流水线意味着您将操作分为多个阶段。假设你有一个乘法器,它对你的时钟速度来说太长了。你把乘数分

我有一些计算正在进行,目前在一个75兆赫的像素时钟上升沿,以输出720p的视频在屏幕上。一些数学运算(比如一些模运算)花费的时间太长(20+ns,而75MHz是13.3ns),所以我的时间限制没有得到满足。我不熟悉FPGA,但我想知道是否有一种方法可以以比当前像素时钟更快的速度运行计算,以便在75MHz时钟的下一个滴答声之前完成计算。顺便说一下,我正在使用VHDL。

FPGA中的复杂数学运算通常是流水线的。流水线意味着您将操作分为多个阶段。假设你有一个乘法器,它对你的时钟速度来说太长了。你把乘数分成三个阶段。基本上,您的乘法器由三个不同的部分组成(它们有自己的时钟输入),一个接一个地链接。这三个部分比一个部分小,因此它们的延迟更小,因此您可以为它们使用更快的时钟

这样做的一个缺点是“延迟”。您的流水线系统将提供延迟输出。在上面的乘法器示例中,要获得正确的输出,必须等待输入通过所有3个阶段。但这通常非常小(当然取决于您的设计),可以忽略

这里有一个关于这个的好帖子:编辑:改为看Brian的帖子


此外,供应商通常在其设计软件中以IP核的形式提供数学运算的优化和流水线版本。寻找它们。

以下是一些技巧:

  • 流水线-将逻辑拆分为多个时钟周期
  • 多周期路径-如果您不需要每个周期的答案,您可以告诉工具,它需要更长的时间。但要小心,不要告诉工具错误的东西
  • 再想一想-例如,您真的需要在非常宽的
    x
    上执行
    x mod 3
    ,还是可以使用连续更新的模3计数器
  • 使用更好的工具-我曾经有过这样的例子,我可以使用昂贵的合成器在深层逻辑路径上满足计时要求,而不是使用供应商的合成器在同一代码上不满足计时要求

更极端的解决方案包括更换硅,以获得更快的设备,或更新的设备,或更新的、更快的设备。

75 MHz按照今天的FPGA标准已经相当慢了

问题是模运算,它实际上包括除法;分裂是缓慢的

仔细考虑您需要的操作,以及是否有任何方法可以重新组织计算。如果你是时钟像素,它不像你有32位整数处理;限制值更容易处理

马丁暗示了一个选择:降低强度。如果你有1280像素/行,并且需要每三个像素操作一次,你不需要计算1280 mod 3!计数0,1,2,0,。。。相反

另外,如果需要8位(或12位)数的模3,则将所有可能的值存储在查找表中,这将足够快

或者有时候你可以乘以1/3(X“5555”)而不是除以3,然后乘以3(这是一个加法)再减去得到模。这条管道非常好,但是由于X“5555”只是1/3的近似值,您需要在模拟中验证它为每个输入提供了正确的输出。(对于16位输入,这不是一个大的模拟!)模9的扩展很容易

编辑:

你的评论中有两点:另一个选择是使用Spartan的时钟生成器创建一个X2时钟(150MHz),它为你提供每像素2个周期。管道化良好的代码应该满足150MHz的要求,不会有太多麻烦

过程(Clk)
开始
如果(上升沿(Clk)),则
对于0到2循环中的i
案例一是
当0=>temp1 temp2结果为空时;
终例;
端环;
如果结束;
结束过程;
首先要认识到的是循环和case语句相互抵消,因此这简化为

PROCESS(Clk)
BEGIN
    if rising_edge(Clk) then
        temp1 <= a*data;
        temp2 <= temp1*b;
        result <= temp2*c;
    end if;
END PROCESS;
过程(Clk)
开始
如果上升沿(Clk),则

temp1如果我有一个操作,例如“1280 mod 3”或“720 mod 9”,如何将其分解为更小的部分?我确实理解流水线,只是不确定模本身是如何流水线的。你应该尝试实现你自己的模函数。然后你就开始用管道输送。但这是另一个话题。天哪,“vhdlguru”管道示例一定是我很久以来见过的最愚蠢的VHDL之一@BrianDrummond作为一个初学者,我的观点可能是无效的,但是,我发现这篇文章非常有益于教学流水线如何工作以及如何实现。如果你有更好的文章,请与我们分享。。。循环和case语句完全不起作用!只留下三份作业。而且它是马车,因为。。。好的,我最好把它编辑到我的答案中。你能发布失败路径的完整代码吗?有很多方法可以优化计时-如果你能给我们一个具体的问题,我们可以给出一个具体的答案(或者至少几个)芯片可以运行得更快(它是spartan6),但只是像素时钟在75MHz,我不知道如何“让其他事情跑得更快”。不过,我现在明白了,我可以数数了。谢谢你解释“如何不使用管道!”。我记得它,因为它在我刚开始时帮助我理解了管道。现在我明白了这是一个非常愚蠢的代码。
PROCESS(Clk)
BEGIN
    if rising_edge(Clk) then
        temp1 <= a*data;
        temp2 <= temp1*b;
        result <= temp2*c;
    end if;
END PROCESS;
PROCESS(Clk)
BEGIN
    if rising_edge(Clk) then
        -- cycle 1
        temp1   <= a*data;
        b_copy  <= b;
        c_copy1 <= c;
        -- cycle 2
        temp2   <= temp1*b_copy;
        c_copy2 <= c_copy1;
        -- cycle 3
        result  <= temp2*c_copy2;
    end if;
END PROCESS;
PROCESS(Clk)
BEGIN
    if rising_edge(Clk) then
        -- cycle 1
        temp1   <= a * data;
        temp2   <= b * c;
        -- cycle 2
        result  <= temp1 * temp2;
    end if;
END PROCESS;