【问题标题】:How to use a fixed point sin function in Vivado HLS如何在 Vivado HLS 中使用定点 sin 函数
【发布时间】:2017-12-05 13:38:11
【问题描述】:

我正在计算极坐标系中两条线的交点:

typedef ap_fixed<16,3,AP_RND> t_lines_angle;
typedef ap_fixed<16,14,AP_RND> t_lines_rho;

bool get_intersection(
        hls::Polar_< t_lines_angle, t_lines_rho>* lineOne,
        hls::Polar_< t_lines_angle, t_lines_rho>* lineTwo,
        Point* point)
{
    float angleL1 = lineOne->angle.to_float();
    float angleL2 = lineTwo->angle.to_float();
    t_lines_angle rhoL1 = lineOne->rho.to_float();
    t_lines_angle rhoL2 = lineTwo->rho.to_float();
    t_lines_angle ct1=cosf(angleL1);
    t_lines_angle st1=sinf(angleL1);
    t_lines_angle ct2=cosf(angleL2);
    t_lines_angle st2=sinf(angleL2);
    t_lines_angle d=ct1*st2-st1*ct2;

    // we make sure that the lines intersect
    // which means that parallel lines are not possible
    point->X = (int)((st2*rhoL1-st1*rhoL2)/d);
    point->Y = (int)((-ct2*rhoL1+ct1*rhoL2)/d);

    return true;
}

在对我们的 FPGA 进行综合后,我看到浮点正弦(和余弦)的 4 种实现每次实现需要 4800 个 LUT,这 4 个函数的总和为 19000 个 LUT。我想通过使用定点正弦来减少 LUT 计数。 I already found a implementationCORDIC 但我不知道如何使用它。该函数的输入是一个整数,但我有一个ap_fixed 数据类型。如何将此ap_fixed 映射到整数?以及如何将我的 3.13 定点映射到所需的 2.14 定点?

【问题讨论】:

    标签: fixed-point trigonometry vivado-hls


    【解决方案1】:

    在我的一位同事的帮助下,我想出了一个非常简单的解决方案,不需要任何手写实现或固定点数据的操作:

    使用#include "hls_math.h" 以及hls::sinf()hls::cosf() 函数。

    重要的是要说函数的输入应该是ap_fixed&lt;32, I&gt;,其中I &lt;= 32。函数的输出可以分配给不同的类型,例如ap_fixed&lt;16, I&gt;

    示例:

    void CalculateSomeTrig(ap_fixed<16,5>* angle, ap_fixed<16,5>* output)
    {
        ap_fixed<32,5> functionInput = *angle;
        *output = hls::sinf(functionInput);
    }
    

    LUT消耗:

    在我的例子中,每个函数实现的 LUT 消耗减少到 400 个 LUT。

    【讨论】:

      【解决方案2】:

      您可以使用位切片来获取 ap_fixed 变量的小数部分和整数部分,然后对它们进行操作以获得新的 ap_fixed。可能是这样的:

      constexpr int max(int a, int b) { return a > b ? a : b; }
      
      template <int W2, int I2, int W1, int I1>
      ap_fixed<W2, I2> convert(ap_fixed<W1, I1> f)
      {
          // Read fraction part as integer:
          ap_fixed<max(W2, W1) + 1, max(I2, I1) + 1> result = f(W1 - I1 - 1, 0);
          // Shift by the original number of bits in the fraction part
          result >>= W1 - I1;
          // Add the integer part
          result += f(W1 - 1, W1 - I1);
          return result;
      }
      

      我还没有很好地测试过这段代码,所以对它持保留态度。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2023-02-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-03-26
        • 1970-01-01
        • 2020-02-16
        相关资源
        最近更新 更多