Neural network 在系统Verilog中计算浮点值的e^x?

Neural network 在系统Verilog中计算浮点值的e^x?,neural-network,verilog,fpga,system-verilog,sigmoid,Neural Network,Verilog,Fpga,System Verilog,Sigmoid,我正在构建一个在FPGA上运行的神经网络,最后一个难题是在硬件上运行一个sigmoid函数。这是: 1/(1 + e^-x) 或 不幸的是,这里的x是一个浮点值(SystemVerilog中的real值) 关于如何在SystemVerilog中实现这两个功能,有什么建议吗 这让我很困惑,因为这两个函数都很复杂,我甚至不知道从哪里开始实现它们,因为它们是浮点值。一个简单的方法是为这个函数创建一个内存/数组。然而,这种选择可能是非常低效的 x应该是内存的输入地址,该位置的值可以是函数的输出 假设函

我正在构建一个在FPGA上运行的神经网络,最后一个难题是在硬件上运行一个sigmoid函数。这是:

1/(1 + e^-x)

不幸的是,这里的x是一个浮点值(SystemVerilog中的
real
值)

关于如何在SystemVerilog中实现这两个功能,有什么建议吗


这让我很困惑,因为这两个函数都很复杂,我甚至不知道从哪里开始实现它们,因为它们是浮点值。一个简单的方法是为这个函数创建一个内存/数组。然而,这种选择可能是非常低效的

x
应该是内存的输入地址,该位置的值可以是函数的输出

假设函数的值如下所示。(这只是一个例子)

因此,您可以为此创建一个数组,用于存储输出值

int a[4] = `{1, 2, 3, 4};

我刚刚用Vivado HLS完成了这个,它允许你用C写电路。 这是我的C代码

#include math.h

void exp(float a[10],b[10])

{
    int i;
    for(i=0;i<10;i++)
    {
        b[i] = exp(a[i]);
    }
}
#包括math.h
void exp(浮动a[10],浮动b[10])
{
int i;

对于(i=0;i,正如您所意识到的,类型real是不可合成的。您需要分别对类型integer尾数和类型integer index进行操作,并在完成后将它们合并,跟踪符号。一旦您处理好(e^-x),其余的应该是直接进行的

请尝试此页面以获取快速解释:


并在“浮点数字设计”上搜索更多解释/示例。

你真的需要一个浮点数吗?定点就足够了吗

考虑(atan(x)+1)/2,x的唯一有用值很可能是那些指数相当小的值。(如果指数很大,你的答案是pi/2)


定点数的atan可以很容易地在硬件中计算;有cordic方法(请参阅)和直接方法;例如,请参阅以硬件(FPGA)为目标的FPGA设计流程通常不支持FPGA结构中的浮点数。精度有限的定点更常用

有限精度定点方法:
使用Matlab为您的数学函数创建一个样本数组,使最大值为+/-.99999。对于8位精度(实际上是带符号位的7位),将这些数字乘以128,在小数点处取整并去掉小数部分。将这些数字以2s补码十六进制格式写入文本文件。在SystemVerilog中,可以使用该文本文件实现ROM。使用$readmemh()将这些数字读入内存样式变量(具有压缩和解压维度的变量).链接到教程:
.
现在你有了一个ROM,它的函数样本精度有限

第21.4节从SystemVerilog规范中的文件加载内存阵列数据提供了$readmh()的定义。下面是文档:

如果您需要浮点,一种可能是使用处理器软核和在FPGA结构中实现的浮点单元,并在该软核上运行软件。该软核通过物理总线(如axi4 steaming)与FPGA结构的其余部分连接。请参阅:
开始吧。
这是一个与普通FPGA设计非常不同的工作流,使用不同的工具。C或C++编译器与数学库(TAN、EXP、DIV等)一起使用,与处理器核一起使用。 固定点的另一种可能性是带有硬核处理器的FPGA。Xilinx Zynq就是其中之一。这是一种复杂而强大的方法。一本免费的书提供了如何使用Zynq的知识
.

由于Zynq是一个更为复杂的平台(硬件处理器和FPGA集成在一个芯片上),因此该工作流程比软核方法更为复杂.

您为哪种FPGA设计?它是否有任何DSP资源?使用FPGA上的DSP块计算sigmoid函数。延迟和吞吐量要求是什么?这将严重影响我为此设计的任何东西。此外,我不熟悉任何可以将实(浮点)合成为硬件的FPGA工具(它可能存在,但如果存在的话,那就是最近的事了)。在许多神经网络计算中,计算可能不需要非常精确。如果您真的实现浮点运算单元,则评估上述方程和复杂实现的成本可能非常高。一种选择是使用定点数学或查找表在特定域范围内实现。
int a[4] = `{1, 2, 3, 4};
#include math.h

void exp(float a[10],b[10])

{
    int i;
    for(i=0;i<10;i++)
    {
        b[i] = exp(a[i]);
    }
}