HLS工具使FPGA上的数学更简单

时间:2016-06-01 13:20:57

标签: vhdl signal-processing verilog fpga

我有一个问题,使用HLS工具比写下原始VHDL / verilog更容易解决。目前我正在使用Xilinx Virtex-7,因为我认为这已经被其他一些供应商解决了。

我可以使用VHDL 2008。

因此,想象一下在VHDL中你有很多计算,例如:

p1 <= a x b - c;
p2 <= p1 x d - e;
p3 <= p2 x f - g;
p4 <= p2 x p1 - p3;

目前,如果我用IP核编写它,它将是四个DSP IP核,并且由于端口宽度不同,我必须生成4次IP核。每当我对其中一些外部信号进行更改时,所有宽度都会再次改变。跟踪所有这些调整大小是一件痛苦的事情,特别是在调整签名向量的大小时。

我有很多数学,因此有很多DSP逻辑。使用HLS工具编写此块会更容易。理想情况下,我希望它能够处理宽度并相应地对数据进行位移。

这样的工具是否存在?你会推荐哪一个?

加分:

这些工具中的任何一个都可以处理浮点数学并让您控制精度吗?

2 个答案:

答案 0 :(得分:6)

有很多方法可以实现目标。但首先要解决你的问题。

  

目前,如果我用IP内核编写它,它将是三个DSP IP内核,并且由于端口宽度不同,我必须生成3次IP内核。

不一定。如果您的输入ag都是固定点,则可以使用ieee.numeric_std或在VHDL-2008中使用ieee.fixed_pkg。这些将推断DSP内核(例如Xilinx上的DSP48)。例如:

-- Assume a, b, and c are all signed integers (or implicit fixed point)
signal a : signed(7 downto 0);
signal b : signed(7 downto 0);
signal c : signed(7 downto 0);
signal p1 : signed(a'length+b'length downto 0); -- a times b produces a'length + b'length +1 (which also corresponds to (a times b) - c adding one bit).
...
p1 <= a*b - resize(c, p1'length);

这将意味着乘数和加法器。

使用UFIXEDSFIXED也可以这样做。但是你需要跟踪位宽。

此外,还有一个浮点包(ieee.float_pkg),但我不建议用于硬件。在定时和资源方面,你最好在定点上实现它。

  

每当我对其中一些外部信号进行更改时,所有宽度都会再次改变。跟踪所有这些调整大小是一种痛苦。

您可以自动执行此操作。看看我上面的例子。您可以根据操作轻松确定宽度。乘法总和位数。添加添加一个位。所以,如果我有:

y <= a * b;

然后我可以将y的长度简单地推导为a'length + b'length。可以办到。然而,问题是有点增长。如果您保持完全精确,您描述的操作链将显着增长。在某些点,您需要截断或舍入以减少位数。这是困难的部分,您可以容忍多少错误取决于算法和预期的数据输入。

  

我有很多数学,因此有很多DSP逻辑。使用HLS工具编写此块会更容易。理想情况下,我希望它能够处理宽度并相应地对数据进行位移。

自动处理是困难的部分。在VHDL中,这不会发生(也不是Verilog)。但是你可以很好地跟踪它并根据需要更新位宽。但它不会自动处理诸如舍入,截断和管理错误界限之类的事情。 DSP工程师应该处理这些问题并指导RTL开发人员使用适当的宽度以及何时进行舍入或截断。

  

这样的工具是否存在?你会推荐哪一个?

在更高级别上有多种选择可以做到这一点。在资源方面,这些都不是特别节俭。 Matlab有一个代码生成工具,可以将Matlab模型(适当构造)转换为RTL。它甚至可以分析舍入,截断等问题,并确定适当的位宽。您可以控制精度,但它是固定点。我们玩过它,发现它远不能生成高效的高速代码。

或者,Xilinx确实有一个HLS套件(参见Vivado)。我并不是都精通这种方法,但据我所知,它允许编写C代码来实现算法。然后合成C #e&#34;在某种执行引擎中执行的东西。您仍然必须将C代码与RTL基础架构接口,这本身就是一个挑战。到目前为止我们没有大力追求它(即使我们做DSP重设计)的原因是将HLS和RTL一起模拟为一个系统是一个很大的挑战。

答案 1 :(得分:1)

过去我发现flopoco在硬件中生成任意数学函数。如果我没记错的话,它支持许多类型的功能。例如,它可以生成算术核心来计算类似a = 3 *sin²(x + pi / 3)的东西。对于这些计算,您可以指定输入/输出的总体精度(浮点/固定点)或输入的宽度(整数)。也可以指定执行频率以及是否管道功能。

以下是我发现的如何使用它的旧教程:tutorial