代码编织梦想

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文件当中。
工程目录

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

3.1 S1_Baseline

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

3.2 S2_Simple_Reconstruction

使用两输入复用器可以不使用sigma变量,在一定程度上减少资源的占用,其实也没少多少…,但是也要提起有这件事,这样可以有意识的用到其他方面。使用两输入复用器最主要的目的是可以高效地实现选择,另外我们使用CORDIC算法就是为了减少复杂运算,因此可以使用移位来进行相应的运算。S2代码
简单的代码重构,对比S1与S2发现
S2报告
DSP资源占用消失了,而且时钟的估计值小了很多!从这可以看出S1、S2虽然都是描述的同一个功能,但是进行代码重构后可以使代码的执行效率好很多。S2分析
乘法运算被移位运算代替了。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

对比综合后的报告可以看出,程序的执行效率更高了。
S3报告
当然还可以继续优化,因为循环之间存在着依赖关系,需要大家手动UNROLL,来展开循环,上个章节已经讲过这个内容了,大家可以尝试优化下,我就不在这里赘述了,显得我太啰嗦。

4. 总结

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

原创不易,切勿剽窃!

在这里插入图片描述

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


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


注:个人精力能力有限,欢迎批评指正!
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_35712169/article/details/100064178

fpga学习笔记---verilog实现cordic算法——fpga求sin函数和cos函数——fpga求actan函数——fpga开平方_dengfenglai123的博客-爱代码爱编程_verilog写sin函数

  参考资料:   https://blog.csdn.net/qq_39210023/article/details/77456031    https://blog.csdn.net/messi_cyc/article/details/77966457   https://wenku.baidu.com/view/6c623aa8910e

【转】cordic_zhangduojia的博客-爱代码爱编程_cordic 算法之圆周系统之旋转模式

【1】https://blog.csdn.net/u010712012/article/details/77755567 1、求cos和sin的思路: 从(x0,0)开始,转过的角度和收敛于theta,在这个迭代的过程中,x收敛于cos,y收敛于sin; 2、求arctan的思路: 从给定的tan(theta)=(x0,y0)开始,往(x1,0)方

cordic--hls实现_诛诸的博客-爱代码爱编程

1. 背景 CORDIC(Coordinate Rotation Digital Computer)坐标旋转数字计算机是一种计算三角函数,双曲函数和其他数学函数的有效技术。CORDIC仅使用加法,减法,位移和表查找来执行简

HLS 开发学习(三)CORDIC算法-爱代码爱编程

文章目录 旋转各种状况90°45° tan ⁡

HLSBOOK学习笔记(二) CORDIC-爱代码爱编程

HLSBOOK学习笔记(二) CORDIC CORDIC算法简介及优化计算正弦和余弦笛卡尔向极坐标转换 写在最前: 这一章介绍的HLS优化方式,是为变量选择正确的数据表示,这也是(一)中所铺垫过的 CORDIC算法简介及优化 CORDIC(Coordinate Rotation Digital Computer),坐标旋转数字计算法,能够计

【Vivado HLS学习之CORDIC算法的实现】-爱代码爱编程

【Vivado HLS学习之CORDIC算法】 先抛出一个问题:在FPGA上怎么实现三角函数sin,cos的计算? 以sin为例,在计算机上实现sin函数可以用泰勒展开来近似。 s i

HLS_1 FPGA并行编程_FIR-爱代码爱编程

fir.cpp #include "fir.h" void fir(data_t *y,data_t x){ coef_t C[N] = {53,0,-91,0,313,500,313,0,-91,0,53}; static data_t shift_reg[N]; acc_t acc; int i; acc = 0; Shift_Accu

FPGA 编程三大范例-爱代码爱编程

注释:本文节选自赛灵思《Vitis 高层次综合用户指南 (UG1399)》v2021.2,仅作为个人学习记录之用,侵删。 虽然 FPGA 可使用 Verilog 或 VHDL 等低层次硬件描述语言 (HDL) 来编程,但现在已有多种高层次综合 (HLS) 工具可以采用以 C/C++ 之类的更高层次的语言编写的算法描述,并将其转换为 Verilog 或 V

HLS / Chisel 实现CORDIC算法计算三角函数(圆坐标系旋转模式)-爱代码爱编程

CORDIC(坐标旋转数字算法)是一种计算三角、双曲和其他数学函数的有效方法。它是一种数字算法,每次运算均产生一次结果输出。这使我们能够根据应用需求调整算法精度;增加运算迭代次数可以得到更精确的结果。 CORDIC是只使用加法、减法、移位和查找表实现的简单算法,这种算法在FPGA中实现效率高,在硬件算法实现中经常用到。 CORDIC CR模式 原理

HLS / Chisel 实现CORDIC算法双曲系统-爱代码爱编程

CORDIC(坐标旋转数字算法)是一种计算三角、双曲和其他数学函数的有效方法。它是一种数字算法,每次运算均产生一次结果输出。这使我们能够根据应用需求调整算法精度;增加运算迭代次数可以得到更精确的结果。 CORDIC是只使用加法、减法、移位和查找表实现的简单算法,这种算法在FPGA中实现效率高,在硬件算法实现中经常用到。 CORDIC算法双曲系统原理