优化神经网络中前馈算法的Verilog代码

时间:2013-02-27 07:52:57

标签: neural-network verilog

编辑:

感谢所有建议。我应该更好地把它放在我原来的问题中,很抱歉不清楚它。行prod [0]< = prod [0] + input [0] x weight1 [i];直到prod [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获得的三个值的最大值,以确定输出应该是什么(这是一个分类问题)。

  7. 上述阶段和每个时钟周期的乘法次数(第1阶段为25,第2阶段为3)是否正常?

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

    非常感谢所有帮助和建议人员,

    费萨尔

    ORIGINAL:

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

    我有一个新设计的想法(在消息的最后),但是想由经验丰富的人运行它,看看它是否比我当前的实现更有效(见下文)或更糟,如果更糟,怎么能我使这么多算术运算更有效率?

    网络上的一些背景知识:

    输入层有200个输入,

    隐藏层有25个神经元,

    输出层有3个输出。

    Verilog代码理念: 我只有一个实现整个算法的模块。

    1. 第一步是将输入(其中200个)与每个神经元的权重(其中200个)相乘(并且有25个神经元) 它计算
    2. 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个神经元的权重相乘:

      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个输出神经元进行计算。

        1. 最后一步是在prod_2 [0到2]上调用sigmoid。我不得不为此实例化3个激活模块。
        2. 模拟结果很棒。但可能非常低效!!!!

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

          Top_Module - &gt;神经元 - &gt;乘法和激活

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

          我的问题:

          1. 在一个模块中执行所有操作的早期实现是否更有效?

          2. 实例化28个神经元,每个神经元实例化200个乘法模块

          3. 使我的代码高效的任何其他想法,以便Synopsys Design Compiler不需要12个小时?!!

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

          5. 对于一个奇怪的问题感到抱歉,但我是整个综合概念的新手,想知道这些工具如何实例化模块?

            谢谢,

            费萨尔。

2 个答案:

答案 0 :(得分:1)

听起来你正试图并行完成所有这些,这意味着很多路由和很多乘法器。

你可能想重新做一些事情,这样你每次只为每个神经元更新一个输入*权重,所以你的0..200循环需要200个滴答才能完成。

答案 1 :(得分:1)

  

使我的代码高效的任何其他想法,以便Synopsys Design Compiler不需要12个小时?!!

之前的建议很好,虽然我看不到您当前的所有设计,但请确保您的模块之间有足够的管道阶段。如果你的关键路径真的很长时间,那么概要会在很长一段时间内试图调整你的乘数以满足可能不可能的时序约束。

通过简化路径约束,降低所需的时钟频率可以使合成更容易。

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