verilog宏功能中dds信号发生器_Cordic算法(sinx,cosx)的Verilog实现

CORDIC(Coordinate Rotation Digital Computer)算法即坐标旋转数字计算方法,是J.D.Volder1于1959年首次提出,主要用于三角函数、双曲线、指数、对数的计算。该算法通过基本的加和移位运算代替乘法运算,使得矢量的旋转和定向的计算不再需要三角函数、乘法、开方、反三角、指数等函数【2】。

为什么要用cordic算法?

首先根据上述的解释,我们可以看出:cordic算法的最大特点是使用加减法和移位操作实现初等函数的计算。在数字电路中,加减法和移位操作耗费资源少且处理速度快,所以cordic算法在硬件中容易实现,而且能起到提高处理速度,降低资源消耗的功能。

在某些特殊情况,比如asic开发,现有的编译软件自带的IP核是不能使用的,比如我最近需要做的东西,需要的信号发生器(正弦波发生器)就只能自己使用verilog进行实现。

设计思路:

cordic算法可以看做是无穷多个旋转向量的合成,在硬件实现时可以理解为无穷次的迭代(当然我们只能使用有限次迭代),基本实现方法默认大家都理解,主要是数据处理时寄存器位数越大,流水线长度越大,输出函数值的精度越高。这里我采用了长度为27的流水线,寄存器位数为32位(有符号,所以实际上1°对应的输入为

)。最终实现了
23、24Bit精度(
量级)

这里主要希望有哪位大侠解释一下我遇到的问题(虽然我解决了,但是没有仔细研究问题产生原因)。

仿真结果及傅里叶分析:

由于有一段时间了,所以只好找一下渣图(modelsim仿真):

f4c1968aa1053e64dfa1eea99478c430.png

当然了,从这个根本看不出精度,所以需要将数据导出并使用MATLAB进行处理分析:

cb491ea5c537d851359828d8493f84a3.png

955400654ba92742d30d555efd59caa6.png

第一个是正弦函数的误差函数,第二个是余弦函数的误差函数。(一个周期内采集了

个点)

testbench是用户自己编写,由于cordic实际上只需要计算[0,90°]的正余弦即可获得整个周期的函数值,但是,sinx与cosx在使用cordic算法时,接近0,90,180,270,360时会出现极大的误差,单纯使用cordic27级流水线最终在这些点处的误差大约为

量级。这tm就很尴尬了,我并没有get到这种现象发生的原因,参考文献【1】的仿真实际上也遇到了这个问题,不过他貌似没有解决。
  • 解决方法

在这些点附近(实际上是

附近)使用泰勒公式的
一次多项式进行逼近,实际上就相当于多了一个switch,只要阈值合理,那么精度是可以保证的。
  • FFT分析

ce731e47702d42c50e8aa22d7b3e675f.png

927835a7f7fecfc857d0598d418f9ba1.png

进行傅里叶分析,主瓣高度与旁瓣高度之比大约为

参考文献:

【1】cordic算法的verilog实现及modelsim仿真 - aikimi7 - 博客园

【2】CORDIC_百度百科

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值