CORDIC(Coordinate Rotation Digital Computer)算法即坐标旋转数字计算方法,是J.D.Volder1于1959年首次提出,主要用于三角函数、双曲线、指数、对数的计算。该算法通过基本的加和移位运算代替乘法运算,使得矢量的旋转和定向的计算不再需要三角函数、乘法、开方、反三角、指数等函数【2】。
为什么要用cordic算法?
首先根据上述的解释,我们可以看出:cordic算法的最大特点是使用加减法和移位操作实现初等函数的计算。在数字电路中,加减法和移位操作耗费资源少且处理速度快,所以cordic算法在硬件中容易实现,而且能起到提高处理速度,降低资源消耗的功能。
在某些特殊情况,比如asic开发,现有的编译软件自带的IP核是不能使用的,比如我最近需要做的东西,需要的信号发生器(正弦波发生器)就只能自己使用verilog进行实现。
设计思路:
cordic算法可以看做是无穷多个旋转向量的合成,在硬件实现时可以理解为无穷次的迭代(当然我们只能使用有限次迭代),基本实现方法默认大家都理解,主要是数据处理时寄存器位数越大,流水线长度越大,输出函数值的精度越高。这里我采用了长度为27的流水线,寄存器位数为32位(有符号,所以实际上1°对应的输入为
这里主要希望有哪位大侠解释一下我遇到的问题(虽然我解决了,但是没有仔细研究问题产生原因)。
仿真结果及傅里叶分析:
由于有一段时间了,所以只好找一下渣图(modelsim仿真):
![f4c1968aa1053e64dfa1eea99478c430.png](https://i-blog.csdnimg.cn/blog_migrate/67ab3b0f9ef0d6351ba44f2e509ce1f3.jpeg)
当然了,从这个根本看不出精度,所以需要将数据导出并使用MATLAB进行处理分析:
![cb491ea5c537d851359828d8493f84a3.png](https://i-blog.csdnimg.cn/blog_migrate/8f7e343919f4db7a6e910577b4a9aa01.png)
![955400654ba92742d30d555efd59caa6.png](https://i-blog.csdnimg.cn/blog_migrate/c82be9c98a97bdd5d50668e890610056.png)
第一个是正弦函数的误差函数,第二个是余弦函数的误差函数。(一个周期内采集了
testbench是用户自己编写,由于cordic实际上只需要计算[0,90°]的正余弦即可获得整个周期的函数值,但是,sinx与cosx在使用cordic算法时,接近0,90,180,270,360时会出现极大的误差,单纯使用cordic27级流水线最终在这些点处的误差大约为
- 解决方法
在这些点附近(实际上是
- FFT分析
![ce731e47702d42c50e8aa22d7b3e675f.png](https://i-blog.csdnimg.cn/blog_migrate/b363eca86d37cf95ccd46661f3b2f4db.png)
![927835a7f7fecfc857d0598d418f9ba1.png](https://i-blog.csdnimg.cn/blog_migrate/3e8c4e97ced84f45aaa30cbb222cfabd.png)
进行傅里叶分析,主瓣高度与旁瓣高度之比大约为
参考文献:
【1】cordic算法的verilog实现及modelsim仿真 - aikimi7 - 博客园
【2】CORDIC_百度百科