如何在 FPGA 中做数学运算

您所在的位置:网站首页 excel表格设置除法公式怎么设置 如何在 FPGA 中做数学运算

如何在 FPGA 中做数学运算

2023-06-02 20:37| 来源: 网络整理| 查看: 265

FPGA 非常适合进行数学运算,但是需要一点技巧,所以我们今天就看看如何在 FPGA 中进行简单和复杂的数学运算。 7917196fc7422763e3bb6281471b6d36.jpeg 介绍

由于FPGA可以对算法进行并行化,所以FPGA 非常适合在可编程逻辑中实现数学运算。我们可以在 FPGA 中使用数学来实现信号处理、仪器仪表、图像处理和控制算法等一系列应用。这意味着 FPGA 可用于从自动驾驶汽车图像处理到雷达和飞机飞行控制系统的一系列应用。

因为 FPGA 寄存器丰富并且包含专用乘法器累加器 (DSP48) 等功能,所以在 FPGA 中实现数学运算需要一些技巧。

3e0c96d36465c2e23eb37620d4002d2a.png c8809efac12c97f7e34a5931b9bf9e71.png

这使它们成为实现定点数学运算的理想选择,但是这与我们倾向于使用的浮点运算不同,因此在进行浮点运算时候我们需要一点技巧。

定点数学运算

定点数的小数点位于向量中的固定位置。小数点左边是整数元素,小数点右边是小数元素。这意味着我们可能需要使用多个寄存器来准确量化数字。幸运的是 FPGA 中的寄存器通常很多。

e6a63bc16ebaee7ae9cd6fd5b6ad59e6.png

相比之下,浮点数可以存储比固定寄存器宽度(例如,32 位)宽得多的范围。寄存器的格式分为符号、指数和尾数,小数点可以浮动,因此直接使用 32 位寄存器时,其能表达的值远远超过 2^32-1。

然而,在可编程逻辑中实现定点数学运算有几个优点,而且实现起来要简单得多。由于定点解决方案使用的资源显着减少,因此可以更轻松地进行布线,从而提高性能,因此在逻辑中进行定点数学运算时可以实现更快的解决方案。

需要注意的一点是,在处理定点数学运算时会使用一些规则和术语。第一个也是最重要的问题之一是工程师如何描述向量中小数点的位置。最常用的格式之一是 Q 格式(长格式的量化格式)。Q 格式表示为 Qx,其中 x 是数字中小数位数。例如,Q8 表示小数点位于第 8 和第 9 个寄存器之间。

我们如何确定必要的小数元素的数量取决于所需的精度。例如,如果我们想使用 Q 格式存储数字 1.4530986319x10^-4,我们需要确定所需的小数位数。

如果我们想使用 16 个小数位,我们将数字乘以 63356 (2^16),结果将是 9.523023。这个值可以很容易地存储在寄存器中;然而,它的精度不是很好,因为我们不能存储小数元素,所以因为9.523023≈9, 9/65536 = 1.37329101563x10^-4。这会导致准确性下降,从而可能影响最终结果。

我们可以使用 28 个小数位,而不是使用 16 个小数位,结果就是 39006(1.4530986319x10^-4 x 2^28) 的值存储在小数寄存器中。这给出了更准确的量化结果。

了解了量化的基础知识后,下一步就是了解有关数学运算小数点对齐的规则。如果我们执行运算操作但是小数点没有对齐,我们就不会得到正确的结果。

加法——小数点必须对齐

减法——小数点必须对齐

除法——小数点必须对齐

乘法——小数点不需要对齐

我们还需要考虑操作对结果向量的影响。不考虑结果的大小可能会导致溢出。下表显示了结果大小调整的规则。

3013b833cb96ca1b0968c3fd9cc88e79.png

假设我们有两个向量(一个 16 位,另一个 8 位),在进行运算的时候将出现以下情况:

C(16  downto  0)= A(15  downto  0)+ B(7  downto  0)

C(16  downto  0)= A(15  downto  0)- B(7  downto  0)

C(22  downto  0)= A(15  downto  0)* B(7  downto  0)

C(8  downto -1)= A(15  downto 0)/ B(7  downto 0)

做除法时的 -1 ,反映了小数元素的寄存器大小的增加。根据所使用的类型,如果使用 VHDL 定点包,这可能是 8 到 -1,如果使用 Q1 时可能是 9 到 0。

关于除法的最后一点说明它可能会占用大量资源,因此通常最好尽可能使用移位实现除法运算。

简单算法

现在我们了解了定点数学的规则,让我们来看看我们如何能够实现一个简单的算法。在这种情况下,我们将实现一个简单的滑动平均(exponential moving average)函数。

要开始使用此应用程序,我们需要先打开一个新的 Vivado 项目并添加两个文件。第一个文件是源文件,第二个文件是测试文件。

library IEEE; use IEEE.STD_LOGIC_1164.ALL; --library ieee_proposed; use ieee.fixed_pkg.all; entity math_example is port(  clk : in std_logic;  rst : in std_logic;    ip_val : in std_logic;  ip : in std_logic_vector(7 downto 0);    op_val : out std_logic;  op : out std_logic_vector(7 downto 0)); end math_example; architecture Behavioral of math_example is constant divider : ufixed(-1 downto -16):= to_ufixed( 0.1, -1,-16 ) ;  signal accumulator : ufixed(11 downto 0) := (others => '0'); signal average : ufixed(11 downto -16 ) := (others => '0'); begin acumm : process(rst,clk) begin    if rising_edge(clk) then      if rst = '1' then          accumulator  '0');         average  '0');     elsif ip_val = '1' then          accumulator  (accumulator + to_ufixed(ip,7,0)-average(11 downto 0)), size_res => accumulator);         average '0'); begin clk_gen : clk '0'); constant a : sfixed(9 downto -32):= to_sfixed( 2.00E-09, 9,-32 );  constant b : sfixed(9 downto -32):= to_sfixed( 4.00E-07, 9,-32 ); constant c : sfixed(9 downto -32):= to_sfixed( 0.0011, 9,-32 );  constant d : sfixed(9 downto -32):= to_sfixed( 2.403, 9,-32 );  constant e : sfixed(9 downto -32):= to_sfixed( 251.26, 9,-32 );  begin cvd : process(clk) begin   if rising_edge(clk) then    op_val       if ip_val = '1' then       store 


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3