当前位置: 首页 > article >正文

CORDIC算法笔记整理

CORDIC算法有两种模式,分别为旋转模式和向量模式。而在数字硬件实现混频处理时,CORDIC算法是比较好的方法,使用的是CORDIC的旋转模式,只需通过移位操作和加法就可以实现频谱搬移的乘法操作。

1 CORDIC算法理解

1.1 单次旋转 

 对于CORDIC算法的理解先从简单的开始——从一个角度\beta的(x1,y1)旋转\theta到角度\varphi的(x2,y2),如下图所示。

假设图中圆的半径为L,则有如下的关系:

cos\beta =\frac{x_{1}}{L}sin\beta =\frac{y_{1}}{L}

cos(\theta +\beta )=\frac{x_{2}}{L}=cos\theta cos\beta -sin\theta sin\beta

sin(\theta +\beta )=\frac{y_{2}}{L}=cos\theta cos+sin\theta sin\beta

因此可以得出如下关系式:

x_{2}=x_{1}cos\theta -y_{1}sin\theta

y_{2}=x_{1}sin\theta +y_{1}cos\theta

对上式提出cos\theta表示成如下:

X_{2}=x_{1} -y_{1}tan\theta=\frac{x_{2}}{cos\theta }

Y_{2}=x_{1}tan\theta +y_{1}=\frac{y_{2}}{cos\theta }

因此每次旋转一个角度\theta对应的x和y都会有个缩放因子cos\theta,旋转结束后需要将总的缩放系数还原。

1.2 多次旋转

上面将的是将一个角度进行单次旋转到另一个角度的表示,如果一个角度需要旋转多次逼近目标旋转角度,可以将单次旋转进行多次,用矩阵的方式来表示则更容易理解,矩阵形式如下图所示。

 以此类推,可以推出(x2,y2)到(x1,y1),(x1,y1)到(x0,y0)的旋转矩阵。

此时缩放系数也好理解,就是K=cosA_{0}cosA_{1}cosA_{2}.....cosA_{n-1}。只要n取得足够大,缩放系数K就无限接近1.647,因此1.647也被用作缩放系数常数。

从(x0,y0)到(x1,y1)旋转第一次的角度记为\theta _{0},从(x1,y1)到(x2,y2)旋转第一次的角度记为\theta _{1},……而我们旋转的角度为A=A_{0}+A_{1}+A_{2}+...+A_{n},因此只需要知道我们需要旋转的角度,就可以实现通过一系列小角度A_{n}的连续旋转来完成。如果规定每次旋转的角度为tanA_{n}=2^{-n},则有利于硬件实现,可以用查表的方式实现tanA_{n}的计算。

nA_{n}tan(A_{n})
0452^{-0}
126.552^{-1}
214.032^{-2}
n2^{-n}

 上图中的s_{n}2^{-n}=tanA_{n},由于A_{n}的角度范围为(-\frac{\pi}{2}, \frac{\pi}{2}),tanA_{n}取值存在负数,而正切表中存放的是正数2^{-n},故s_{n}为符号位,对应当前输入A_{n}位于(-\frac{\pi}{2}, 0)还是(0, \frac{\pi}{2}),大于0则符号位为正,小于0则符号位为负。

2 CORDIC在频谱搬移数字实现中的应用 

频谱搬移包括了上变频(DUC)和下变频(DDC),其实现的理论框图如下图所示。

他们可以通过NCO(数控振荡器)产生特定频率的载波信号实现频谱的搬移,也可以通过CORDIC算法实现频谱的搬移。前者需要用到乘法器和NCO模块,对于硬件资源很紧俏的情况,一般会选择CORDIC算法,因为它只需要通过加法器和移位器实现。

在DDC中输入信号表示为cos(w_{b}t+w_{c}t+\varphi )sin(w_{b}t+w_{c}t+\varphi ),其中w_{b}t=2\pi f_{b}tw_{c}t=2\pi f_{c}tf_{b}为信号频率,f_{c}为载波频率,\varphi为固定相位。DDC的目标是去掉载波,保留信号,即最终需要的是信号为cos(w_{b}t ),即需要将输入信号旋转的角度为\Theta =w_{c}t+\varphi,其中t=nT=n\frac{1}{f_{s}}=\frac{n}{f_{s}},T为采样周期,f_{s}为采样率。因此DDC输入信号可表示为cos(\frac{2nf_{b}\pi}{f_{s}}+\frac{2nf_{c}\pi}{f_{s}}+\varphi )sin(\frac{2nf_{b}\pi}{f_{s}}+\frac{2nf_{c}\pi}{f_{s}}+\varphi ),因此DDC每次输入以下信号的瞬时相位为\frac{2nf_{b}\pi}{f_{s}}+\frac{2nf_{c}\pi}{f_{s}}+\varphi,需要旋转的角度为\frac{2nf_{c}\pi}{f_{s}}+\varphi

换一种方式理解,由于数字系统的输入数据是连续不断的,每个输入数据为cos(\frac{2nf_{b}\pi}{f_{s}}+\frac{2nf_{c}\pi}{f_{s}}+\varphi ),也就是说每个输入数据需要去掉的相位为\frac{2nf_{c}\pi}{f_{s}}+\varphi,即只需要知道输入信号的初始相位\varphi和相位步进\frac{2f_{c}\pi}{f_{s}}以及输入的序号n,便可知道每个输入数据对应需要去掉的相位。

输入的数据都需要将\frac{2nf_{c}\pi}{f_{s}}+\varphi旋转到0,即每个输入数据都需要旋转多次将角度逼近0,旋转的次数越多越逼近0,次数越多逼近的角度越小,具体需要旋转的次数依据算法能接受的算法性能和精度来选取。

同样的在DUC中输入信号为cos(\frac{2nf_{b}\pi}{f_{s}})sin(\frac{2nf_{b}\pi}{f_{s}}),在DUC后需要输出的信号为cos(\frac{2nf_{b}\pi}{f_{s}}+\frac{2nf_{c}\pi}{f_{s}}+\varphi )sin(\frac{2nf_{b}\pi}{f_{s}}+\frac{2nf_{c}\pi}{f_{s}}+\varphi ),因此旋转的角度依然是\frac{2nf_{c}\pi}{f_{s}}+\varphi

需要注意的点是,在DDC中需要将\frac{2nf_{c}\pi}{f_{s}}+\varphi逐次旋转到0,在DUC中是需要将0旋转到\frac{2nf_{c}\pi}{f_{s}}+\varphi。即只要知道了载波频率和信号采样率,就可以通过cordic算法实现频谱的搬移。

需要注意的一点是:由于数字系统输入信号的初始相位不能准确的知道,所以设计时将初始相位最好设计成寄存器可配,方便后期调整。

3 参考资料

参考文献:

[1] 耿丹,CORDIC算法研究与实现,遥测遥控,2007.11, vol.28

[2] 杨林,OFDM系统NS-CFR技术研究与实现,2023.6

 

如有错误不对处,欢迎指出。


http://www.kler.cn/a/323606.html

相关文章:

  • unittest和pytest
  • Day 65 || SPFA、判断负权回路、bellman_ford之单源有限最短路
  • springboot 文件高效上传
  • CondaError: Run ‘conda init‘ before ‘conda activate‘解决办法
  • 计算机网络HTTP——针对实习面试
  • PCA 原理推导
  • 全局中断总开关位与各个中断源对应的寄存器使能位开启顺序
  • Vscode把全部‘def‘都收起来的快捷键
  • Django 对数据库的增删改查
  • [译] K8s和云原生
  • `torch.utils.data`模块
  • PostgreSQL 向量扩展插件pgvector安装和使用
  • 高等数学 第11讲 多元函数偏导数的计算与应用_复合函数求偏导_隐函数求偏导_条件极值
  • 什么是原生IP?
  • QT+ESP8266+STM32项目构建三部曲二--阿里云云端处理之云产品流转
  • 学习threejs,绘制二维线
  • 洛谷P1197.星球大战
  • 一道简单的css动态宽度问题?
  • List 循环遍历删除元素
  • 精通推荐算法31:行为序列建模之ETA — 基于SimHash实现检索索引在线化
  • rtsp 协议推流接收(tcp udp)
  • 【深度学习】(9)--调整学习率
  • 后端返回内容有换行标识,前端如何识别换行
  • Linux:LCD驱动开发
  • MySQL:进阶巩固-存储过程
  • 经典Python应用库一览