使用Xilinx CORDIC IP核生成正、余弦波

本文介绍如何调用Xilinx的CORDIC IP核生成某一频率的正弦波和余弦波。

主要是CORDIC IP核的设置,下面对其具体参数的设置进行了说明。

标注1:选择函数的类型,这里选择sin和cos。

标注2:选择CORDIC的结构,是字串行还是并行,这里选择并行。

标注3:选择输出流水线类型,这里选择不要流水线。

标注1:选择相位角格式,其中Radians单位为弧度,Scaled Radians单位为多少PI弧度,这里选择Scaled Radians。

标注2:选择输入相位角的数据位宽,我们选择16位。

标注3:舍位模式,选择近似值。

对于相位角的格式这里做具体详细说明:

当相位角设置为Radians时,相位角的取值范围为:-PI<=PHASE_IN<=PI;

当相位角设置为Scaled Radians时,相位角的取值范围为:-I<=PHASE_IN<=1。

数据有效值的定义:

相位角:第一位为符号位,第二、三位为整数位,其余为小数位;

X_out:第一位是符号位,第二位是整数位,其余为小数位;

Y_out:第一位是符号位,第二位是整数位,其余为小数位。

对于有符号数,整数部分为二进制补码。

标注1:选择阶乘和精度,0表示根据数据来自动选择。

标注2:选择CORDIC算法的范围,将输出值控制在-PI/4~+PI/4之间还是-PI~+PI之间。

标注3:选择输出,此处选择RDY来查看什么时候输出数据有效。

如果要生成正余弦波,Coarse Rotation 必须选上,让输出数据是整个圆平面。

由于我们设置的数据为16位的Scaled Radians模式,所以PHASE_IN的取值范围从-1.0到+1.0对应的16进制为:

16'he000和16'h2000。假如我们的相位角从0开始以16‘h00c0自增,Modelsim仿真结果如图4所示:

这是因为当phase_in的值大于+1.0或小于-1.0时,CORDIC IP核会当作+1和-1计算,一直保持相同的值。

从上述仿真结果可以看出,分段出现的波形是完整的,只是没有很好的衔接上。对此我们采用下面的方法使波形衔接。我们选取X_OUT的两个波谷做一个周期,找到两个波谷所对应的PHASE_IN,使两个波谷之间对应的PHASE_IN值不断重复,即可得到完美的正弦波。

为了方便查看,我们增加了cnt计数器。在第一个波谷附近我们找到正弦输出信号的最值点所对应的相位值。方法如下所示:先在仿真波形上选取一段完整的正弦波,如图6.1所示。然后,找出第一个波谷所对应的cnt值,大概在301左右,如图6.2所示。再将正弦输出信号转换为16进制有符号数,在301附近找到最值点-16379,找出此值对应的相位16'helc0。



第二个波谷所对应的相位值的查找如下图所示:


第二个波谷所对应的cnt值大概为389,对应的正弦输出信号的最值为:-16384,对应的相位值为:16’h2180。

修改程序中的phase赋值部分,如下所示:

修改程序后,仿真得到的波形,如下图所示:

下板子测试得到的波形:

16'h00C0 -> 0000 0000 1100 0000,按照datasheet的phase数据格式:000,0 0000 1100 0000,也就是十进制的0.0234375。而这个数的角度值为:0.0234375 * 180° = 4.21875°,也就是每个clk步进4.21875°。

一个圆有360°,那么从0°到360°一共步进360° / 4.21875° 约等于 85.3次。
我选择的clk为30.24M,即33ns,也就是85.3 * 33ns输出一个完整的正弦余弦波。
所以正弦余弦波的周期为1 /85.3 * 33ns 约等于 0.35Mhz。

在chipscope中将采集到的正余弦信号数据存储为.txt格式,使用matlab处理数据得到的正弦波频率如下图所示,接近0.35Mhz:

参考文献:
[1] http://blog.sina.com.cn/s/blog_40a27f6a0102uzpv.html .
[2] http://blog.163.com/fantasy_sunny/blog/static/1959182122013113152237210/ .

文章来源:yundanfengqing_nuc的专栏

1 条评论

(1楼)前面你说的波形不完整

cmflyme 在 星期二, 10/23/2018 - 20:32 发表。

前面你说的波形不完整 其实是每次累加16’h00c0不能被整除而已换成可以整除的因子就没问题了。