浮点分频器硬件实现细节

Ver*_*ian 8 hardware algorithm math floating-point verilog

我试图在硬件中实现一个32位浮点硬件分频器,我想知道我是否可以得到任何关于不同算法之间的权衡的建议?

我的浮点单元目前支持乘法和加法/减法,但我不打算将其切换到融合乘法 - 加法(FMA)浮点架构,因为这是一个嵌入式平台,我试图最小化区域使用.

Spe*_*tre 6

很久以前,我遇到了当时军事 FPU 中使用的这种简洁且易于实现的浮点/定点除法算法:

  1. 输入必须是无符号且移位的,因此x < y两者都在范围内< 0.5 ; 1 >

    不要忘记存储班次sh = shx - shy和原始符号的差异

  2. 找到f(通过迭代)所以y*f -> 1....之后 x*f -> x/y是除法结果

  3. x*f向后移动sh并恢复结果符号(sig=sigx*sigy)

    可以x*f像这样轻松计算:

    z=1-y
    (x*f)=(x/y)=x*(1+z)*(1+z^2)*(1+z^4)*(1+z^8)*(1+z^16)...(1+z^2n)
    
    Run Code Online (Sandbox Code Playgroud)

    在哪里

    n = log2(num of fractional bits for fixed point, or mantisa bit size for floating point)
    
    Run Code Online (Sandbox Code Playgroud)

    您还可以z^2n在固定位宽数据类型上为零时停止。

[Edit2] 有一些时间和心情,所以这里是 32 位 IEEE 754 C++ 实现

我删除了旧的(bignum)示例,以避免未来的读者感到困惑(如果需要,它们仍然可以在编辑历史记录中访问)

z=1-y
(x*f)=(x/y)=x*(1+z)*(1+z^2)*(1+z^4)*(1+z^8)*(1+z^16)...(1+z^2n)
Run Code Online (Sandbox Code Playgroud)

我想保持简单,所以还没有优化。例如,您可以将所有*=0.5和替换*=2.0为指数inc/dec...如果您与float运算符上的 FPU 结果进行比较/,这将不太精确,因为大多数 FPU 在 80 位内部格式上计算,而此实现仅在 32 位上。

正如你所看到的,我只是使用 FPU 的+,-,*. 这些东西可以通过使用快速 sqr 算法来加速,例如

特别是如果你想使用大位宽度......

不要忘记实施标准化和/或上溢/下溢校正。