2013-02-27 52 views
1

编辑:优化我的Verilog代码神经网络中的前馈算法

感谢您的所有建议。我应该更好地把这个问题放在我原来的问题中,对于不清楚这个问题感到抱歉。行prod [0] < = prod [0] + input [0] x weight1 [i];直到产品[25]被执行超过200个时钟周期。但是,这26次乘法确实同时发生。一次是否太多,或者是否需要在一个时钟周期内执行1次乘法(32位x 32位),这意味着在200 x 26个时钟周期内进行所有200 x 26次乘法运算?

另外,我有6个阶段到管道整个事情通过:

  1. 26并联矩阵乘法重复200次(200个时钟周期)。

  2. 设置一个控制标志,以便由具有大约200个元素的LUT组成的激活模块可以完成它的工作并发送结果。每个神经元重复25次(超过25个时钟周期)。

  3. 重置标志停止激活功能。重置计数器和一切准备下一部分。

  4. 3个矩阵乘法并行重复25次(25个时钟周期)。

  5. 再次呼叫激活功能。

  6. 查找从6中获得的三个值的最大值,以确定输出应该是什么(这是一个分类问题)。

以上阶段和每个时钟周期的乘法次数(阶段1中的25次和阶段2中的3次)是否正常?

或者我应该重做它执行阶段2超过200x25时钟周期和阶段4执行超过10x3时钟周期?

非常感谢所有帮助和建议的家伙,

费萨尔

ORIGINAL:

我已经编写,并模拟了人工神经网络的前馈算法模块。综合工具需要很长时间(Synopsys DCS和Xilinx ISE 14.4)......它已经运行了9个多小时,所以我对它的感觉非常糟糕!模拟结果是正确的。

我对NEW设计有一个想法(在消息结尾处),但想由有经验的人来运行它,看看这是否更有效率,我目前的实施(见下文)或更糟糕,如果更糟,我可以使这么多算术运算更有效率吗?

在网络上的一些背景:

输入层有200个输入,

隐层具有25个神经元,

输出层有3个输出。

Verilog代码思路: 我只有一个模块实现了整个算法。

  1. 第一步是乘以权重(其中200)的输入端(其中200),用于每个神经元(也有25个神经元) 它计算

prod[0] <= prod[0] + input[0] x weight1[i]; i = 0 to 200-1

.......

prod[25] <= prod[25] + input[25] x weight1[i]; i = 0 to 200-1

和上面重复200个输入中的每一个都是200次。它同时进行所有25个神经元的计算。

  1. 接下来,对上述结果调用ANN激活函数。这是通过使用具有接近200个元素的LUT(我使用case语句)完成的。为此,我编写了另一个activation.v文件,并且必须为每个神经元实例化25次!

  2. 接着,乘以权重以上的结果的最后3个神经元:

prod_2[0] <= prod_2[0] + prod[0]*weight2[i]; i = 0 to 25-1;

prod_2[1] <= prod_2[1] + prod[0]*weight2[i]; i = 0 to 25-1;

prod_2[2] <= prod_2[2] + prod[0]*weight2[i]; i = 0 to 25-1; ,反复进行上述25次,每次的25个刺激输入。它同时对所有3个输出神经元进行计算。

  1. 最后一步是在prod_2 [0到2]上调用sigmoid。我必须为此实例化3个更多的激活模块。

模拟结果很好。但可能非常低效!

所以,我想知道这是否是一个更好的主意?

Top_Module - >神经元 - >乘法和激活

顶部模块调用的神经元功能(需要实例28元这个!),并把相关的输入和权重了。神经元函数调用乘法模块(第一部分需要200个,第二部分需要25个)。神经元函数接下来添加上述200个结果(第2部分中的25个)并调用激活函数。输出最终返回到Top_Module。

我的问题:

  1. 这是更有效,越早实施这是一个模块中执行的一切吗?

  2. 就是实例28层的神经元和神经元的每个实例200个乘法模块

  3. 任何其他的想法,使我的代码有效,使Synopsys设计编译器不需要12小时?

  4. 如果我这样做,每个神经元有200个输入和200个权重,这将是它的输入端口。我不认为Verilog模块可以相互传递数组。如果没有,我必须手动写出所有的400端口而不是传递数组吗?

对不起一个奇怪的问题,但我是新来的整体综合概念,并想知道这些工具如何去实例化模块?

谢谢,

费萨尔。

+0

200次乘法运算真的很大。你的设计在每次乘法之间看起来很相似,所以我认为你可以声明它是一个模块并使用generate。可能是这样更快。 – Khanh 2013-02-27 08:58:37

+0

太好了。非常感谢这个建议......我会尽力而为,希望它会更有效率。 – 2013-02-27 09:07:40

回答

1

听起来就像你正试图做所有这些并行,这意味着很多路由和大量的乘法器。

您可能需要重新工作,以便每次只更新一个输入*权重,因此您的0..200循环需要200个滴答完成。

+0

那么,行prod [0] <= prod [0] + input [0] x weight1 [i];直到产品[25]被执行超过200个时钟周期。对不起,在我的文章中没有澄清。但是,这26次乘法确实同时发生。一次是否太多,或者是否需要在一个时钟周期内执行1次乘法(32位x 32位),这意味着在200 x 26个时钟周期内进行所有200 x 26次乘法运算?这是否更好? – 2013-02-27 21:56:45

1

任何其他的想法,使我的代码有效,使Synopsys设计编译器不需要12小时?

先前的建议很好,虽然我看不到所有当前的设计,但确保在模块之间有足够的流水线阶段。如果您的关键路径对于时间安排来说真的很长,那么故事梗概会在很长一段时间里试图调整您的乘法器以满足可能不可能的时序约束。

同时减少所需的时钟频率可以通过简化路径约束来使合成更容易。另外,如果你确实保留了200个乘法器(并不是说你应该这样做),那么查看'综合分区'将会很有用,但是如何做到这一点将取决于你使用的综合工具。基本上,你合成一个模块/分区,然后只需复制该分区多次,而不是一次尝试合成所有模块。正如你的设计可能试图独立优化通过所有200个乘法单元的路径,实际上你可以为每个乘法单元使用相同的综合网表。这里有一些关于xilinx的信息:http://www.xilinx.com/support/documentation/application_notes/xapp918.pdf