《FPGA并行编程》读书笔记(第一期)03_CORDIC

《FPGA并行编程》读书笔记(第一期)03_CORDIC

  • 0. 内容回顾
  • 1. 绪论
  • 2. 读书笔记源码说明
  • 3. 3个Solution带您理解CORDIC算法
    • 3.1 S1_Baseline
    • 3.2 S2_Simple_Reconstruction
    • 3.3 S3_Pipeline
  • 4. 总结

0. 内容回顾

上节内容量非常大,那可是小编耗时将近14个小时来呈现给大家的,大家都弄懂了吗?这节实验就比较少了,没有新知识,主要是大家自己主动阅读CORDIC算法并搞懂。本次推送附带高亚军老师的Vivado HLS中的数据类型章节来帮助大家理解上节的位宽优化,以及本章的数据表示。

  • 第5讲 如何处理任意精度的数据类型
  • 第6讲 数据类型的转换
  • 第7讲 Vivado HLS 中的复合数据类型
  • 第8讲 在 Vivado HLS 中应用 C/C++ 基本运算

1. 绪论

CORDIC (Coordinate Rotation Digital Computer) 是坐标旋转数字计算机算法的简称,由Vloder于1959年在设计美国航空导航控制系统的过程中首先提出,主要用于解决导航系统中三角函数、反三角函数和开方等运算的实时计算问题。。它是一种数字算法, 每次运算均产生一次结果输出。这使我们能够根据应用需求调整算法精度;增加运算迭代次数可以得到更 精确的结果。运算精度与运算性能和占用资源并列,是一种通用的设计评估指标。CORDIC是只使用加法、减法、移位和查找表实现的简单算法,这种算法在FPGA中实现效率高,在硬件算法实现中经常用到。
CORDIC算法是1950年由Jack Volder发明,它最开始是作为数字解决方案替代模方案应用于B-58轰 炸机实时导航上,它的功能是计算旋转角度。在那个时代用硬件实现乘法的成本是相当高的,同时 CPUs的计算能力也非常有限。因此这个算法需要有低的运算复杂度和使用简单的运算操作。多年之后,它被应用于数学协处理器、线性系统、雷达信号处理、傅立叶变换和其它数字信号 处理算法中。现在,它广泛应用于FPGA设计中。Vivado HLS用CODIC进行三角函数计算,同时CORDIC也是现代FPGA IP CORE库中的标准运算模块。

引自《FPGA并行编程》第三章 CORDIC。

本节课的实验内容较少,主要是读懂《FPGA并行编程》中的CORDIC算法,并利用上节课学过的一些优化方案来进行优化。小编感觉如果最初对CORDIC算法不是很熟悉的话,至少阅读两遍才可以能有比较好的认识,大家在做实验之前一定要搞懂前面的算法内容哦,后面我会说明原因的,小编就因为没有弄懂这个算法的机理,后面吃了不少苦头。

小编认为CORDIC算法的本质就是利用一些简单的移位、查找表、加法操作,来逼近正余弦的计算,既减少了资源的占用,又提高了计算速度,但同时在不影响准确性的情况下牺牲了一定的精度。大家阅读完CORDIC算法是怎么看待的呢!欢迎在后台与小编进行进一步的交流。
本章的重点是《FPGA并行编程》的第三章节内容!实验仅仅是回顾。
本章的重点是《FPGA并行编程》的第三章节内容!实验仅仅是回顾。
本章的重点是《FPGA并行编程》的第三章节内容!实验仅仅是回顾。

2. 读书笔记源码说明

本章内容的源代码见PP4FPGAS_Study_Notes_S1C03_HLS_CORDIC
工程文件组织和第二章节一致,只是把#define内容移到了.h文件当中。
《FPGA并行编程》读书笔记(第一期)03_CORDIC_第1张图片

3. 3个Solution带您理解CORDIC算法

3.1 S1_Baseline

首先我们要做的当然是C Simulation了,小编在学习这章内容的时候,被这个仿真坑了许久,下面让我一一道来。
我拿着从英文原版书籍的Github上下载的代码,准备开始仿真,仿真就结果让我百思不得其解,大家看下图便可得知。
《FPGA并行编程》读书笔记(第一期)03_CORDIC_第2张图片
得到如此的结果,真的非常尴尬。小编又重读了一遍CORDIC算法,再看了一遍作者的代码,才发现一行代码少了一个正负控制的乘法。
《FPGA并行编程》读书笔记(第一期)03_CORDIC_第3张图片
修改后方得到正确的结果《FPGA并行编程》读书笔记(第一期)03_CORDIC_第4张图片
我在此说明这件事没有啥意思,我认为代码时作者故意写错的,作者几乎不可能犯下如此低级的错误。大家对一段代码进行重构优化之时,了解其所使用的算法含义非常重要,否则连别人给你挖了个坑都不知道,到最后算法调试的时候发现结果不对,还找不到原因,这就只能怪自己了。大家别嫌我啰嗦,我就是感觉有所心得的东西基本都分享所来了,大家各取所需呀。
仿真后开始综合,看看初始代码的一些性能估计和资源利用率。《FPGA并行编程》读书笔记(第一期)03_CORDIC_第5张图片

3.2 S2_Simple_Reconstruction

使用两输入复用器可以不使用sigma变量,在一定程度上减少资源的占用,其实也没少多少…,但是也要提起有这件事,这样可以有意识的用到其他方面。使用两输入复用器最主要的目的是可以高效地实现选择,另外我们使用CORDIC算法就是为了减少复杂运算,因此可以使用移位来进行相应的运算。《FPGA并行编程》读书笔记(第一期)03_CORDIC_第6张图片
简单的代码重构,对比S1与S2发现
《FPGA并行编程》读书笔记(第一期)03_CORDIC_第7张图片
DSP资源占用消失了,而且时钟的估计值小了很多!从这可以看出S1、S2虽然都是描述的同一个功能,但是进行代码重构后可以使代码的执行效率好很多。《FPGA并行编程》读书笔记(第一期)03_CORDIC_第8张图片
乘法运算被移位运算代替了。S2ashr

3.3 S3_Pipeline

对该循环使用PIPELINE

#ifdef S3_Pipeline

void cordic(THETA_TYPE theta, COS_SIN_TYPE &s, COS_SIN_TYPE &c)
{
  // Set the initial vector that we will rotate
  // current_cos = I; current_sin = Q
  COS_SIN_TYPE current_cos = 0.60735;
  COS_SIN_TYPE current_sin = 0.0;

  // This loop iteratively rotates the initial vector to find the
  // sine and cosine values corresponding to the input theta angle
  for (int j = 0; j < NUM_ITERATIONS; j++) {
#pragma HLS PIPELINE
      // Multiply previous iteration by 2^(-j).  This is equivalent to
      // a right shift by j on a fixed-point number.
      COS_SIN_TYPE cos_shift = current_cos >> j;
      COS_SIN_TYPE sin_shift = current_sin >> j;

    // Determine if we are rotating by a positive or negative angle
    if(theta >= 0) {
        // Perform the rotation
        current_cos = current_cos - sin_shift;
        current_sin = current_sin + cos_shift;

        // Determine the new theta
        theta = theta - cordic_phase[j];
    }
	else {
        // Perform the rotation
        current_cos = current_cos + sin_shift;
        current_sin = current_sin - cos_shift;

        // Determine the new theta
        theta = theta + cordic_phase[j];
    }
  }

  // Set the final sine and cosine values
  s = current_sin;  c = current_cos;
}


#endif

对比综合后的报告可以看出,程序的执行效率更高了。
《FPGA并行编程》读书笔记(第一期)03_CORDIC_第9张图片
当然还可以继续优化,因为循环之间存在着依赖关系,需要大家手动UNROLL,来展开循环,上个章节已经讲过这个内容了,大家可以尝试优化下,我就不在这里赘述了,显得我太啰嗦。

4. 总结

对比上章本章内容略显单薄,实验内容较少,而且没啥新内容;理论内容阅读起来比较困难,需要多阅读思考几遍。实话说我对CORDIC算法的理解不是很深刻,所以本节课没有带了很多干货,也请见谅。再提一下大家要对CORDIC算法有个清晰明了的认识,后面还要用到这个算法呢。希望大家留言反馈,这样可以修改不合理的地方,增加小伙伴们阅读体验。

原创不易,切勿剽窃!

在这里插入图片描述

欢迎大家关注我刚创建的微信公众号——小白仓库
原创经验资料分享:包含但不仅限于FPGA、ARM、Linux、LabVIEW等软硬件开发。目的是建立一个平台记录学习过的知识,并分享出来自认为有用的与感兴趣的道友相互交流进步。



最后要提的是,本文很多资料都是Xilinx大学计划提供,该公众号提供很多的权威信息、开源项目、开发板租借,强烈推荐对FPGA感兴趣的道友关注——XIlinx学术合作。


注:个人精力能力有限,欢迎批评指正!

你可能感兴趣的:(《FPGA》读书笔记(第一期))