编辑:
感谢所有的建议。我应该更好地把这个放在我原来的问题中,很抱歉不清楚。行 prod[0] <= prod[0] + input[0] x weight1[i]; 最多 prod[25] 被执行超过 200 个时钟周期。但是,这 26 次乘法确实是并行发生的。一次太多了,还是我需要在一个时钟周期内进行 1 次乘法(32 位 x 32 位),这意味着在 200 x 26 时钟周期内进行所有 200 x 26 次乘法?
此外,我有 6 个阶段来完成整个过程:
26 个并行矩阵乘法重复 200 次(200 个时钟周期)。
设置一个控制标志,以便由具有大约 200 个元素的 LUT 组成的激活模块可以执行其操作并发送结果。每个神经元重复 25 次(超过 25 个时钟周期)。
重置标志以停止激活功能。重置计数器和一切为下一部分做准备。
3 次并行矩阵乘法重复 25 次(25 个时钟周期)。
再次调用激活函数。
找出从 6 中获得的三个值的最大值,以确定输出应该是什么(这是一个分类问题)。
上述阶段和每个时钟周期的乘法次数(阶段 1 为 25,阶段 2 为 3)是否可以?
或者我应该重做它以在 200x25 时钟周期内执行第 2 阶段,并在 10x3 时钟周期内执行第 4 阶段?
非常感谢所有帮助和建议的家伙,
费萨尔
原来的:
我已经为人工神经网络中的前馈算法编写并模拟了一个模块。综合工具需要很长时间(Synopsys DCS 和 Xilinx ISE 14.4)……它已经运行了 9 多个小时,所以我对此感觉非常糟糕!但模拟结果是正确的。
我有一个新设计的想法(在消息末尾),但想由有经验的人运行它,看看这是否比我当前的实现更有效(见下文)或更糟,如果更糟,我该怎么做许多算术运算更有效?
一些网络背景:
输入层有 200 个输入,
隐藏层有 25 个神经元,
输出层有 3 个输出。
Verilog 代码理念:我只有一个实现整个算法的模块。
- 第一步是将输入(其中 200 个)乘以每个神经元(并且有 25 个神经元)的权重(其中 200 个)它计算
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 个神经元进行计算。
接下来,对上述结果调用 ANN 激活函数。这是通过使用具有近 200 个元素的 LUT 来完成的(我使用了 case 语句)。为此,我编写了另一个 activation.v 文件,并且必须为每个神经元实例化 25 次!
接下来,它将上述结果与最后 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 个 prod 输入中的每一个重复上述 25 次。它同时对所有 3 个输出神经元进行计算。
- 最后一步是在 prod_2[0 到 2] 上调用 sigmoid。为此,我不得不再实例化 3 个激活模块。
模拟结果很棒。但可能非常低效!!!!
所以,我想知道这是否是一个更好的主意?
Top_Module -> 神经元 -> 乘法和激活
顶部模块调用神经元函数(为此需要实例化 28 个神经元!)并将相关的输入和权重传递给它。神经元函数调用乘法模块(第一部分需要 200 个,第二部分需要 25 个)。神经元函数接下来将上述 200 个结果(以及第 2 部分中的 25 个)相加并调用激活函数。输出最终返回到 Top_Module。
我的问题:
这是否比在一个模块中执行所有操作的早期实现更有效?
实例化 28 个神经元,每个神经元实例化 200 个乘法模块是好是坏?
有没有其他想法可以让我的代码高效,从而使 Synopsys 设计编译器不需要 12 小时?!!
如果我这样做,每个神经元都有 200 个输入和 200 个权重,这将是它的输入端口。我不认为 Verilog 模块可以在彼此之间传递数组。如果没有,我是否必须手动写出所有 400 个端口而不是传递数组?
对不起一个奇怪的问题,但我对整个综合概念还是陌生的,想知道这些工具如何实例化模块?
谢谢,
费萨尔。